本文以制作基于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. 关于端口对外的暴露
Dockfile中定义的Expose是针对容器体系来说的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的优先级最高,一般来说对外的服务都需要加上这个参数