1. 什么是Docker
Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口。它是目前最流行的 Linux 容器解决方案。
Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了 Docker,就不用担心环境问题。
总体来说,Docker 的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。
2. 安装Docker
在 Mac 上,可以通过两种方式安装 Docker
使用 homebrew 安装
Homebrew 的 Cask 已经支持 Docker Desktop for Mac,因此可以很方便的使用 Homebrew Cask 来进行安装
brew cask install docker
手动下载安装
可以在 docker官网 下载到安装包。 Docker 的安装为 dmg 文件,与 MacOS 其他软件一样,只需双击打开,把跟鲸鱼一样的图标拖拽到 Application 文件中即可。 然后就可以在启动台中查找 Docker 应用了。 <img src=’https://md-1252929012.cos.ap-guangzhou.myqcloud.com/uPic/xU9gD9.png’ alt=‘xU9gD9’/
Docker的基本概念
Docker 包括两个基本概念
- 镜像(Image)
- 容器(Container)
镜像(Image)
Docker会将应用程序和依赖打包成一个镜像,有了这个镜像后,你就可以通过 Docker 运行生成容器实例。 镜像还可以继承于另一个镜像,比如你可以继承一个已经安装好 nodejs 的基础镜像,然后你就可以在你的镜像里运行 node 应用了。 实际开发中,我们都会基于其他人提供的镜像来制作自己的镜像。为了方便共享,image 文件制作完成后,可以上传到网上的仓库。Docker 的官方仓库 Docker Hub 是最重要、最常用的 image 仓库。
容器(Container)
镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的 类 和 实例 一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。 容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的 命名空间。因此容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。
3. Docker hello world
做为一名合格的程序员,入门一个新东西,怎么可以不输出一个hello world呢,现在就试试一个最简单的hello world。
获取镜像
和git有点类似,Docker 通过 pull 命令拉取去远程仓库拉取镜像。
docker pull hello-world
执行完以上命令后,可以在镜像列表中看到 pull 下来的镜像
docker images
和 docker image ls
命令均可以查看镜像列表
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 12 months ago 13.3kB
REPOSITORY 是仓库名,TAG为生成镜像时打的tag,默认拉取最新tag,即latest,也可以拉取指定tag,比如hello-world:1.0
。每生成一个镜像就会有一个IMAGE ID,CREATED为创建时间,SIZE为镜像大小。
运行镜像
有了镜像之后我们就可以运行镜像生成容器了。 运行一下命令,即可运行镜像。
# docker run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
以上便是运行 hello-world 镜像后生成容器,容器输出的内容。
通过 docker ps
可以查看正在运行的容器Container。但是hellow-world容器执行后会 exit(0) 退出,通过以下命令就可以看到所有运行过的镜像容器
# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
df8e1a0c16b0 hello-world "/hello" 2 minutes ago Exited (0) 2 minutes ago busy_curie
4. 制作一个 Node 服务镜像
先用以下命令创建一个node项目
mkdir node-http && cd node-http
npm init -y
创建 index.js
const http = require("http");
http
.createServer((req, res) => {
res.end("hello docker");
})
.listen(6666);
现在我们可以通过运行 node index.js 来启动我们的服务了,那怎么样才能将我们的服务用docker启动呢? 首先创建一个 Dockerfile 文件
FROM node:8.4
COPY . /node-http
WORKDIR /node-http
RUN npm install --registry=https://mirrors.tencent.com/npm/
EXPOSE 6666
CMD node index.js
一般情况下还会创建 .dockerignore 文件,这个文件类似于.gitignore,这个文件里写明的文件或文件夹,不会被打包到镜像中。
Dockerfile文件的含义如下:
- FROM node:8.4:该 image 文件继承官方的 node image,冒号表示标签,这里标签是8.4,即8.4版本的 node。
- COPY . /node-http:将当前目录下的所有文件(除了.dockerignore排除的路径),都拷贝进入 image 文件的/node-http目录。
- WORKDIR /node-http:指定接下来的工作路径为/node-http。
- RUN npm install:在/app目录下,运行npm install命令安装依赖。注意,安装后所有的依赖,都将打包进入 image 文件。
- EXPOSE 6666:将容器 6666 端口暴露出来, 允许外部连接这个端口。
- CMD node index.js:运行该镜像时,执行该命令,启动我们的node服务。
接下来我们就可以创建镜像了。
docker build -t node-http .
// or
docker build -t node-http:0.01 .
-t 指定镜像名称。 完成之后,通过 docker images 就可以查看到我们的镜像了。
运行镜像
docker run -p 8080:6666 -d node-http
上面命令的各个参数含义如下:
- p参数:容器的 6666 端口映射到本机的 8080 端口。
- d:后台运行镜像。
- node-http:image 文件的名字(如果有标签,还需要提供标签,默认是 latest 标签)。
运行完成之后,就可以通过 6666 端口,访问到node服务啦
docker run 命令还有很多其他的参数,具体可以网上查找或者查看参考链接。