Extra05 - Docker - 容器化

此篇为番外,未收入在本篇的原因是 Docker 是个复杂的工具,因此需要更多的篇幅介绍此工具,但是以本篇的篇幅不足以说明 Docker 的操作,因此放入番外作为补充。

在开发时,我们需要在电脑中安装各式各样的工具与套件後,才能进行开发。这过程中,常会遇到与环境相关的问题,在部署时同样也会因为环境的问题,而需要针对各个环境去排除问题。这些问题都会使开发进度延宕,造成时间上的花费。

使环境容器化 - Docker

Docker 会将应用跑在一个可以独立运作的容器中,这个容器不会被宿主环境所影响,因此我们可以将它随意的执行在任何支援 Docker 的环境中,而不被环境本身与应用程序中使用的技术所限制。

有了 Docker ,我们不再需要在意目标环境的情形,只要确保容器运作正常,就可以将它部署至任何机器中,不管什麽作业系统,只要支援 Docker ,就可以藉由指令启动执行,藉以省下配置的时间,专注在开发与优化的作业上。

安装 Docker

使用 Homebrew 安装 Docker :

brew install docker

安装完後,确认是否安装成功:

> docker --version
Docker version 20.10.7, build f0df350

使用 Docker

在使用 Docker 容器前,我们需要决定使用的 Image 。 在 Docker Hub 中可以找到各式各样的 Image ,选择好後(以 node 举例)使用 Docker 提供的指令将 Image 拉到本机:

docker pull node
# equal
docker pull node:latest

每个 Image 都会有多个版本,如果向例子这样没有指定版本时, Docker 会帮我们拉回 tag 为 latest 的版本。

取得想要的 Image 後,可以使用 docker run 指令建立容器并执行指令:

> docker run -it node
Welcome to Node.js v16.7.0.
Type ".help" for more information.
> console.log('Hello, world!')
Hello, world!

范例中,我们使用 -it 参数,叫 Docker 在本机终端上开启容器内部的终端,我们就可以在容器内部的终端中直接使用 node 指令。

在执行 docker run 时会去检查是否有此 image ,如果没有会帮忙下载後,再执行容器。

使用 docker ps 会列出目前正在执行的容器:

> docker ps
CONTAINER ID  IMAGE   COMMAND                 CREATED         STATUS    PORTS     NAMES
113787a04cc8  node    "docker-entrypoint.s…"  9 minutes ago   Up 9      minutes   sweet_davinci

我们可以使用 docker exec 对目前已经在执行的容器下指令:

> docker exec 113787a04cc8 touch /tmp/tmp.js

在使用 docker exec 时需要指定容器的 ID ,後面在输入要执行的指令。

要停止容器,可以使用 docker stop

docker stop

它会送出停止讯号给容器,并在一段时间後关闭容器。

关闭的容器使用 docker ps -a 才能看到。

要删除容器可以使用 docker rm

docker rm 113787a04cc8

docker images 可以列出目前本机的 images :

> docker images
REPOSITORY      TAG       IMAGE ID       CREATED         SIZE
node            latest    c66552d59c4b   4 days ago      907MB
ubuntu          latest    1318b700e415   3 weeks ago     72.8MB

docker rmi 可以删掉 Image :

docker rmi c66552d59c4b

要删掉 image ,要在没有容器使用的情况下才可以删除,可以使用 -f 参数强制删除 image 。

Dockerfile

Dockerfile 是个 Docker image 的定义档,使用 docker build 可以执行 Dockerfile 中的指令建置 image , Dockerfile 是一个由各种指令组成的档案,描述如何建置 image 。

下面就是一个最简单的 dockerfile

FROM node

Dockerfile 的属性值很多,每个都有不同的功能,详细的说明可以参考官网的介绍

使用 docker build 建立 image :

docker build -t test-node/latest .

-t 是设定 image 的名称,如果没有设定,需要以 id 来指定 image 。

如果当前目录下有 dockerfile 档案的话,直接使用 . 来表示要抓当前目录的 dockerfile 设定档,如果设定档不在当前目录,要使用路径配置。

建置完後使用 docker run test-node/latest 就可以用此 image 建立容器。

Docker Compose

一个应用程序常常都需要多个服务合作,才能正常运作,像是 MEAN 架构就是 MongoDB 、 Express.js 、 Angular 与 Node.js 所组成的。

将所有的套件安装在同一个容器中会使弹性降低,使容器化原本期望达到的高弹性部署打了折扣,为此,我们需要将各组件拆到不同的容器中,并将这些容器整合使用。

Docker Compose 让使用者可以用 docker-compose.yml 档案配置多个容器,并让它们互相沟通运作。

version: '3.3'

services:
  mongo:
    image: mongo

  mongoexpress:
    image: mongo-express
    ports:
      - '8081:8081'
    links:
      - mongo
    environment:
      - ME_CONFIG_MONGODB_URL=mongodb://mongo:27017

上例使用 docker compose 启动 MongoDB 与它的管理工具 mongo-express

Compose 的设定方式,可以参考官网的详细说明

接着下指令执行:

docker-compose up

docker compose 会启动两个容器 mongomongoexpress

清理 Docker

要清理不用的 image 、 container 、 volume 与 network ,可以使用各个对应指令的 prune 。

# Delete all unused network
docker network prune

# Delete all unused volume
docker volume prune

# Delete all unused containers
docker container prune

# Delete all unused images
docker image prune -a

# Delete all unused stuff
docker system prune --volumes

本文重点整理

  • Docker 让开发与部署时更有弹性,我们不再需要花时间在安装各种套件上,可以把心力放在开发与优化上。

参考资料


<<:  注意!所以会点开来!

>>:  Day36 - Windows 提权(7)-提权手法统整 Registry 相关

入门魔法 - function 函式

前情提要 艾草:「你可以帮我算一下 100 + 100 是多少吗?」 「200 啊...」 艾草:「...

码农最後的哄擡价格,高级操作:说出一口聚合分析(上?!)

dog.com来源 这就是现在目前这个业界奇怪的地方 面试时手撕tomcat,要你喷出一堆莫名奇妙...

每日挑战,从Javascript面试题目了解一些你可能忽略的概念 - Day30

tags: ItIron2021 Javascript 前言 终於最後一天啦,实际上写了几篇之後我就...

每秒几十万上下 - 1分K 当冲策略是否有搞头 ?!

最近股市只有一个字 怕.jpg 今天研究了大多的回测策略,大多都是以日计算,想想可不可以用 1分K ...

JavaScript学习日记 : Day11 - 函数绑定

当object中的function作为callback function传递给setTimeout时...