前言
什么是docker?
通俗的理解,docker是创建和管理容器的一种技术。那什么是容器呢?容器的功能与虚拟机很近似,都是在一个物理主机上运行多个操作系统的技术。最大的不同之处在于,虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。
基本概念
- 镜像
Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。我们可以通过命令或者一些基础镜像,构建自己需要的镜像。
- 容器
容器可以看作镜像的实体,容器可以被创建、启动、停止、删除、暂停等。
为什么使用docker
我们知道在部署node.js的应用时,需要已经安装node与npm,如果涉及数据库的话,还需要有数据库的环境和数据库信息。在启动应用时,还需要安装程序依赖的第三方库。如果只是单纯的在一台机器上部署的话,感觉还好。但是如果我们需要在很多机器上部署该应用的话,按照一般的方法,就需要在多个机器上不断地重复搭建应用所需要的环境,这是一个很费时间的过程。如果我们采用docker的形式,就可以在本地创建一个应用程序的镜像(包含程序运行所需要的一切环境),然后只需要在远程主机上传我们创建的镜像,然后使用docker根据镜像创建运行应用进程的容器,轻松几行命令就可以在多个主机上运行我们的程序。
环境说明
本文中所有操作均在Ubuntu 16.0上进行。
前期准备
本文读者熟悉node.js技术,已经可以使用node.js搭建一个简单的应用。所以,本文说明中不包含具体的node.js代码教程。此外,本文的node.js设计MySql存储,不涉及数据库的可以直接从第三节开始看起。
一、安装docker
参考文章
二、MySQL容器制作
拉取MySQL数据库镜像
docker pull mysql/mysql-server:tag
tag: 想要拉取的镜像的版本号 (比如, 5.5, 5.6, 5.7, 8.0, or latest).这里用的是5.7。
不建议使用8.0或者latest。新版本的mysql有些操作跟之前的不太一样,按照网上大多数教程处理可能会有意想不到的错误。本人已经踩坑。
运行MySQL数据库容器
sudo docker run --name db-manage -d -e MYSQL_ROOT_PASSWORD=password -p 3306:3306 mysql/mysql-server:5.7
–name db-manage: 命名MySQL镜像运行的容器的名称
-d detach,在后台运行容器。
-e MYSQL_ROOT_PASSWORD=123(或者是 –env)环境变量 – 参数告诉 docker 所提供的环境变量MYSQL_ROOT_PASSWORD=password:设置数据库root账户密码为password
-p 3306:3306(或者 –publish) 告诉引擎用户想要将容器内的3306端口映射到外部的3306端口上。
mysql/mysql-server:5.7 : 是拉取的mysql数据库镜像
添加从外部访问数据库的权限
MySQL默认是不能从外部网络访问的,默认只能使用本地IP(127.0.0.1)访问。我们待会需要运行node.js的容器具有访问运行MySQL服务的容器的权限。
或许你会觉得很疑惑,都是在一台机器上,不应该是一个IP地址么?
并不是这样。因为实际的主机会为每个运行在其上面的容器单独分配IP,所以不同容器之间,IP地址并不一样。
1.进入MySQL容器
sudo docker exec -it db-manage bash
db-manage:运行MySQL的容器名称
2.在容器中进入Mysql服务
mysql -uroot -ppassword
root:数据库用户名
password:之前运行容器时设置的数据库密码
3.添加外部访问权限
运行以下命令(若之前拉的MySQL版本高于5.7,会报错。因为之后版本的MySQL添加用户权限方式的命令不是下列所展示,具体请参考官网)
# 切换数据库
USE mysql;
# 给root账户开放所有ip访问权限
GRANT ALL PRIVILEGES ON *.* TO "root"@"%" IDENTIFIED BY "password" WITH GRANT OPTION;
# 更新权限设置
FLUSH PRIVILEGES;
MySQL命令已分号结尾
必须使用FLUSH PRIVILEGES更新权限设置才有效
如果只想为指定IP连接MySQL数据库赋予权限,使用一下命令:(更多给MySQL添加用户权限可以参考这篇文章)
# 给root账户开放192.168.1.3访问权限
GRANT ALL PRIVILEGES ON *.* TO "root"@"192.168.1.3" IDENTIFIED BY "password" WITH GRANT OPTION;
三、node程序容器制作
拉取node.js基础镜像
sudo docker pull node:tag
tag 想要拉取的镜像的版本号。这里使用9.11.2-jessie 参考docker公共镜像官网(/node/”>https://hub.docker.com//node/)
制作自己的node.js服务镜像
前提准备:
1. 已经有可以运行的node.js程序
2. node.js链接数据库的设置如下:
const address = {
host : process.env.DATABASE_HOST || 'localhost',
user : 'root',
password : 'choosealife',
port: process.env.PORT || '3306',
database: 'manage',
};
1.进入程序文件夹根目录
cd node-app
2.创建Dockerfile文件(文件名不能更改)
touch Dockerfile
文件内容如下:
# 选择之前下载的node基础镜像 node:<version>
FROM node:9.11.2-jessie
#将当前文件夹下所有文件加入需要制作的镜像中, 在 'manage' 文件夹中.
ADD . /manage
# 下载所需要的包
RUN cd /manage;
npm install --production
# 定义程序默认端口
EXPOSE 3000
# 运行程序命令(manage是ADD添加的文件夹名称, server.js是自己的程序启动入口文件)
CMD ["node","/manage/server.js"]
3.制作镜像
sudo docker build -t node-image-name .
注意: node-imge-name是镜像名称。命令后有一个 . , 不能忘记了。
4.运行node程序镜像并关联运行的MySQL容器
sudo docker run --name manage-system -it -p 3000:3000 --link db-manage:db-manage -e DATABASE_HOST=db-manage node-manage-image
- docker run -it 在容器里运行 docker 镜像,使用交互式终端。
- -p 3000:3000 将宿主机的3000 端口映射到容器的3000 端口上
- link db-manage:db-manage 连接到名为 db-manage的 容器上,并且用 db-manage 指代该容器
- -e DATABASE_HOST=db-manage 将在node.js数据库连接中设置的环境变量 DATABASE_HOST 设置为 db-manage
- node-image-name 是在容器内运行的镜像名称
四、上传docker镜像到远程仓库
上传到docker hub
参考文章
上传到腾讯云服务器
参考文章
上传到阿里云服务器
参考文章
五、常用docker命令
1.获取基础镜像
sudo docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]
2.制作镜像
# 需要提前创建构建文件Dockerfile, version不是必须, 默认为latest, . 表示当前目录
sudo docker build -t imgae-name:version .
3.查看镜像
sudo docker image ls
4.删除镜像
sudo docker image rm image-name
5.已指定镜像创建容器
sudo docker run -it image-name
6.启动已经存在的容器
sudo docker container start container-name
7.停止已经运行的容器
sudo docker container stop container-name
8.重启已经运行的容器
sudo docker container restart container-name
9.查看所有容器
sudo docker container ls -a
10.删除容器
# 删除指定容器, 加上-f可以强制删除正在运行的容器
sudo docker container rm container-name
# 清除所有处于终止状态的容器
sudo docker container prune