Docker教程:四、创建镜像几种最常用的方式(前端工程师)

326 阅读4分钟

方式一:通过Dockerfile创建

在Docker中创建镜像最常用的方式,就是使用Dockerfile。Dockerfile是一个Docker镜像的描述文件,我们可以理解成火箭发射的A、B、C、D…的步骤。Dockerfile其内部包含了一条条的指令,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。 下面以熟悉前端的vue项目为例,介绍怎么写 Dockerfile 文件,实现让用户在 Docker 容器里面运行npm run build编译生成静态代码,并把编译生成的文件推到nginx容器中(静态服务器)。 首先利用vue-cli脚手架工具创建一个vue项目

vue create vue-project
cd vue-project

在项目的根目录下,新建一个文本文件.dockerignore,写入下面的内容。

.git
node_modules
npm-debug.log

上面代码表示,这三个路径要排除,不要打包进入 image 文件。如果你没有路径要排除,这个文件可以不新建。
然后,在项目的根目录下,新建一个文本文件 Dockerfile.multi,写入下面的内容。

# node镜像仅仅是用来打包文件
FROM node:alpine as builder

ENV PROJECT_ENV production


COPY package*.json /app/

WORKDIR /app

RUN npm install --registry=https://registry.npm.taobao.org

COPY . /app

RUN npm run build

# 选择更小体积的基础镜像
FROM nginx:alpine

COPY nginx.conf /etc/nginx/conf.d/nginx.conf

COPY --from=builder /app/dist /app/dist

这个是Docker的多层构建配置文件。先基于node环境启动一个容器,编译生成文件。然后再启动一个nginx容器,把文件推到nginx容器中。
这种多层构建方式有一个好处是使得启动的容器比较小,nginx容器实际只有几十兆。另外,设计模式中有一个概念是单一职责原则,这里每个容器实现的功能需要单一,不能是编译文件和开启静态服务器的功能放在同一个容器中。
接下来在项目目录下,再新建一个nginx.conf文件,这个是之后需要打包进nginx镜像中的,作为nginx的配置文件:

server {
    listen       80;
    server_name  localhost;

    location / {
        root   /app/dist; # 打包的路径
        index  index.html index.htm;
        try_files $uri $uri/ /index.html; # 防止重刷新返回404
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

因为是单页面应用,所有的路由逻辑都在js中,所以所有请求地址的正则匹配都指向index.html
接下来正式打包镜像:

# -f 指定使用Dockerfile.multi进行构建
docker build -t Tony/vue-project-multi . -f Dockerfile.multi

启动容器

docker run -d --name vue-project-multi  -p 8001:80 Tony/vue-project-multi

如果你安装是的Docker Toolbox,就是说你的容器都是运行在Oracle VM VirtualBox

则你需要执行下面的命令:

# 查看虚拟机名字,一般都是叫default
docker-machine ls
# 查看虚机地址,例如:192.168.99.100
docker-machine ip default

然后浏览器中打开192.168.99.100:8001
如果不是安装的Docker Toolbox,则直接在浏览器中打开localhost:8001 即可查看到页面

方式二:修改已有镜像(commit的形式)

先启动一个容器,比如nginx容器。
然后进容器内部做一些你想做的修改,比如用yum或apt-get下载一些软件,或则增删修改一些配置文件。
修改后,执行:

# -m 来指定提交的说明信息,跟我们使用的版本控制工具一样
# -a 可以指定更新的用户信息
# 0b2616b0e5a8 容器ID
# Tony/nginx:1.0.0 指定目标镜像的仓库名和 tag 信息
docker commit -m "my nginx,modify" -a "Tony" 0b2616b0e5a8 Tony/nginx:1.0.0

创建成功后会返回这个镜像的 ID 信息。
使用 docker images 来查看新创建的镜像。

Docker镜像保存为文件及从文件导入镜像的方法

我们制作好镜像后,有时需要将镜像复制到另一台服务器使用。
能达到以上目的有两种方式,一种是上传镜像到仓库中(本地或公共仓库),但是另一台服务器很肯能只是与当前服务器局域网想通而没有公网的,所以如果使用仓库的方式,只能自己搭建私有仓库。 如果我们仅仅是要复制到另外少数的服务器,搭建私有仓库显然没有这个必要,而将镜像保存为文件上传到其他服务器再从文件中载入镜像也是一个不错的选择。
可以使用Docker save和Docker load命令来存储和载入镜像。

# my-nginx.tar 要保存的文件名
# 1312423bf3ee 镜像ID,或则镜像名称
# -o output的意思
docker save -o my-nginx.tar  1312423bf3ee

查看当前目录,发现多了一个my-nginx.tar文件
从文件载入镜像:

# -i input的意思
docker load -i my-nginx.tar