通过实例来创建一个Nginx 应用镜像,理解创建镜像步骤。
准备好以下文件
root@aliyun:example# tree .
.
├── Dockerfile
└── index.html
0 directories, 2 files
Dockerfile 文件
base images
All Docker images start from a
base image
.
A base image is the same images from theDocker Registry
which are used to start containers.
Along with the image name, we can also include theimage tag
to indicate which particular version we want, by default, this islatest
所有的 Docker 镜像都需要基于一个base image
FROM nginx:1.11-alpine # 基于 nginx:1.11-alpine 这个基础镜像构建 nginx 应用镜像
copy 相关文件到 docker image
COPY allows you to copy files from the
directory
containing the Dockerfile to thecontainer's image
.
COPY index.html /usr/share/nginx/index.html # 将应用相关文件复制到镜像中相关文件夹
开放端口,对外服务
Using the
EXPOSE <port>
command you tell Dockerwhich ports
should be open and can be bound to.
You can define multiple ports on the single command, for example, EXPOSE 80 433 or EXPOSE 7000-8000.
EXPOSE 80
定义应用启动命令
define the command that
launches
the application.
The CMD line in a Dockerfile defines thedefault command
to runwhen a container is launched
.
If the command requires arguments then it’s recommended to use an array, for example [“cmd”, “-a”, “arga value”, “-b”, “argb-value”], which will becombined together
and the command cmd -a “arga value” -b argb-value would be run.
CMD ["nginx","-g","daemon off;"]
完整 Docker file
FROM nginx:1.11-alpine
COPY index.html /usr/share/nginx/index.html
EXPOSE 80
CMD ["nginx","-g","daemon off;"]
index.html 内容
<h1>Hello, nginx!</h1>
docker build 制作镜像
root@aliyun:example# docker build -t myapp:v1 .
Sending build context to Docker daemon 3.072kB
Step 1/4 : FROM nginx:1.11-alpine #1
1.11-alpine: Pulling from library/nginx
709515475419: Pull complete
4b21d71b440a: Pull complete
c92260fe6357: Pull complete
ed383a1b82df: Pull complete
Digest: sha256:5aadb68304a38a8e2719605e4e180413f390cd6647602bee9bdedd59753c3590
Status: Downloaded newer image for nginx:1.11-alpine
---> bedece1f06cc
Step 2/4 : COPY index.html /usr/share/nginx/index.html #2
---> 54604ee74078
Step 3/4 : EXPOSE 80 #3
---> Running in d67b9a19bae3
Removing intermediate container d67b9a19bae3
---> d445f315dfa0
Step 4/4 : CMD ["nginx","-g","daemon off;"] #4
---> Running in 37922caeb43a
Removing intermediate container 37922caeb43a
---> f0054c020122
Successfully built f0054c020122
Successfully tagged myapp:v1
root@aliyun:example# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myapp v1 f0054c020122 28 seconds ago 54.3MB
docker run 启动容器
root@aliyun:example# docker run -d -p 8989:80 myapp:v1
92a4851d68a893ae206d6034bd2a703241afca46d87583431cd8f8247fdd4533
root@aliyun:example# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
92a4851d68a8 myapp:v1 "nginx -g 'daemon of…" 4 seconds ago Up 2 seconds 443/tcp, 0.0.0.0:8989->80/tcp naughty_dhawan
root@aliyun:example# docker exec -it naughty_dhawan /bin/sh # 进入容器
/ # hostname
92a4851d68a8
/ # cd /usr/share/nginx/ #查看容器中的 index.html
/usr/share/nginx # ls
html index.html
/usr/share/nginx # cat index.html
<h1>Hello, nginx!</h1>
由上可知,docker 镜像中的
/usr/share/nginx/index.html
就是从主机拷贝的。
分享镜像
root@aliyun:example# docker save -o myappv1.tar myapp:v1 # 镜像保存为 tar 文件
root@aliyun:example# ll *.tar
-rw------- 1 root root 55920640 Nov 7 10:51 myappv1.tar
root@aliyun:example# docker load < myappv2.tar # 装载 tar 文件
Loaded image: myapp:v1
查看解压后的 myappv1.tar
查看镜像分层
root@aliyun:tar# tar -xf myappv1.tar
root@aliyun:tar# ls
19a3c3bc0572a58f29be5d06b28db88cd159c52e386d47de253d6c41f21e7e81
278aa45094fda49d5f1241e0f84fe5b5ee6743c97ae265b52ceceda3b44be58d
34470d46fea52393079a0745396c4122b646b1619852b66c6cc77441b6204d28
3cde60226a035b83e036672471dd6fe889c4aeecfa6f3ebfd54f32a70b899ead
b3128a7c6a22b396d311a9032760820d836d629c54c646d3dc032809d0160bd4
f0054c0201220fa246dd9c81cb00066532168040ac5d6d0601df9115652dc3aa.json
manifest.json
myappv1.tar
repositories
查看镜像层次
root@aliyun:tar# cat repositories
{"myapp":{"v1":"34470d46fea52393079a0745396c4122b646b1619852b66c6cc77441b6204d28"}}
查看镜像仓库信息 “image name”:{“tage”:“最上层的文件”}
查看镜像配置清单
root@aliyun:tar# cat manifest.json
[{"Config":"f0054c0201220fa246dd9c81cb00066532168040ac5d6d0601df9115652dc3aa.json","RepoTags":["myapp:v1"],"Layers":["3cde60226a035b83e036672471dd6fe889c4aeecfa6f3ebfd54f32a70b899ead/layer.tar","b3128a7c6a22b396d311a9032760820d836d629c54c646d3dc032809d0160bd4/layer.tar","19a3c3bc0572a58f29be5d06b28db88cd159c52e386d47de253d6c41f21e7e81/layer.tar","278aa45094fda49d5f1241e0f84fe5b5ee6743c97ae265b52ceceda3b44be58d/layer.tar","34470d46fea52393079a0745396c4122b646b1619852b66c6cc77441b6204d28/layer.tar"]}]
格式化后的 manifest.json
[
{
"Config":"f0054c0201220fa246dd9c81cb00066532168040ac5d6d0601df9115652dc3aa.json",
"RepoTags":[
"myapp:v1"
],
"Layers":[
"3cde60226a035b83e036672471dd6fe889c4aeecfa6f3ebfd54f32a70b899ead/layer.tar", # 镜像第一层
"b3128a7c6a22b396d311a9032760820d836d629c54c646d3dc032809d0160bd4/layer.tar", # 镜像第二层
"19a3c3bc0572a58f29be5d06b28db88cd159c52e386d47de253d6c41f21e7e81/layer.tar", # 镜像第三层
"278aa45094fda49d5f1241e0f84fe5b5ee6743c97ae265b52ceceda3b44be58d/layer.tar", # 镜像第四层
"34470d46fea52393079a0745396c4122b646b1619852b66c6cc77441b6204d28/layer.tar" # 镜像最上层
]
}
]