一路狂飙

制作一个docker镜像

本文以制作基于centos的nginx镜像为例,来说明如何做一个可控的镜像。

step 1. 先基于centos的基础镜像,启动一个叫mynginx的容器

$ docker run -it--name mynginx centos /bin/bash

step 2. 基于该容器做镜像改造,以下操作是在容器内操作


# 新建 nginx yum仓库文件

$ cat > /etc/yum.repos.d/nginx.repo <<EOF
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/\$basearch/
gpgcheck=0
enabled=1
EOF

# 安装 Nginx, -y 表示自动确认
$ yum -y install nginx

# 顺便修改下主页文件
$ echo'<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html

# 退出容器,我们容器部分的安装就算完成了
$ exit

当然如果简单的话,可以直接写到 Dockerfile 中,这种方式适合哪种对Dockerfile的各种奇葩语法搞不懂,需要copy各种数据,安装软件比较复杂,例如需要编译需要各种依赖等等。等同于你拿到一个全新的系统做的一些初始化工作,能变成你们公司的基础镜像,后续的镜像都可以基于这个镜像来构建。

step 3. 在宿主机上提交这个容器,使它变成一个镜像


# 提交前可以看下相对于镜像更新了哪些文件
$ docker diff mynginx

# 用commit命令提交成一个名字叫做mynginx镜像
$ docker commit -a'michael<mching.08@gmail.com>'-m'install nginx' mynginx mynginx

step 4. 使用 DockerFile 构建最终的镜像, dockerfile的的内容如下

新建一个文件夹/tmp/mknginx,编写Dockerfile,名字一定是这个。

FROM mynginx
EXPOSE 80

# 包装一层启动命令
CMD ["nginx", "-g", "daemon off;"]

step 5. 关于端口对外的暴露

  1. Dockfile中定义的 Expose是针对容器体系来说的
  2. docker run -p 80:80中定义的是针对外部系统来说的

下用将这两种情况组合,变成四种实例:

  • Dockerfile 未定义了 Expose 运行时也没加上 run -p 参数

只能在此容器内部使用,不能被link的container访问,不能被外部访问

  • 只在 Dockerfile里定义 Expose了这个端口

能在此容器内部使用,能被link的container访问,不能被外部访问

  • 同时在 Dockerfile里定义了Expose,又在运行时加上了 run -p

能在此容器内部使用,能被link的container访问,能被外部访问

  • 只有 run -p

同上面的情况,所以可以看出 run -p的优先级最高,一般来说对外的服务都需要加上这个参数