一般来说,我们所说的“构建镜像”并不是真正的从零构建一个全新的镜像,而是修改一个已有的基础镜像(如ubuntu)。
创建Docker Hub账号
(1) 如果要存储和分发我们构建的新镜像,那么可以将镜像发布到 Docker Hub 或者自己私有的Registry上面。所以需要先在 Docker Hub 创建一个账号。
(2)创建账号后,使用 docker login
命令就可以登录到Docker Hub了。
# docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: sweeneys
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
如上所示,登录的个人认证信息被保存到 ~/.docker/config.json
使用commit命令创建镜像
1、创建容器
创建一个基于ubuntu镜像的容器,后续会以这个容器为基础进行修改,从而形成新的镜像。
# docker run -it ubuntu /bin/bash
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
7ddbc47eeb70: Pull complete
c1bbdc448b72: Pull complete
8c3b70e39044: Pull complete
45d437916d57: Pull complete
Digest: sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d
Status: Downloaded newer image for ubuntu:latest
2、添加Apache软件包
Apache软件包在ubuntu官方源上的名字为apache2。
root@51753edb3a70:/# apt-get update
root@51753edb3a70:/# apt-get install apache2
3、提交容器
为了避免以后每次创建容器的时候都重新添加Apache, 我们可以使用 docker commit
命令将 当前容器的状态(容器快照)
保存下来形成一个新的镜像。
(1)退出容器:
root@51753edb3a70:/# exit
exit
(2)提交容器:
# docker commit 51753edb3a70 apache2
sha256:a2ffe8f3ca2f02d3b0a202640ed5da45f81761fa6141c2dfa4bd99bb158d42fb
说明:
a.51753edb3a70
为刚刚添加了apache的容器ID。
b.apache2
为仓库名。
(3)查看新镜像
# sudo docker images apache2
REPOSITORY TAG IMAGE ID CREATED SIZE
apache2 latest bd1e81d3fd76 3 minutes ago 188MB
如上所示, apache2
仓库中 IMAGE ID 为 bd1e81d3fd76
的镜像即为刚刚创建的新镜像。
(4)以新镜像创建一个容器
sudo docker run -it apache2 /bin/bash
root@6ed53ad4fc3d:/#
使用Dockerfile构建镜像
1、创建Dockerfile文件
Dockerfile文件使用基于DSL(Domain-special Language)语法的指令来构建一个Docker镜像。
# mkdir static_web
# cd static_web/
static_web# touch Dockerfile
说明:
(1)创建 static_web
目录用来保存Dockerfile, 则static_web
目录就是我们的构建环境(build environment), Docker 把构建环境称为 构建上下文(build context)
或者 上下文(context)
。
2、编写Dockerfile 文件
# version 0.0.1
FROM ubuntu:18.04
MAINTAINER sweeneys "952328342@qq.com"
RUN apt-get update && apt-get install -y nginx
RUN echo 'Hi, I am in your contianer.' > /usr/share/nginx/html/index.html
EXPOSE 80
说明:
(1)Dockerfile由命令和参数组成,命令必须全部大写,参数不可少,如:FROM ubuntu:18.04 。
(2)命令从上到下执行,大体流程如下:
a.Docker从基础镜像(FROM命令指定的镜像)运行一个容器。
b.执行一条指令,对镜像进行修改。
c.执行类似 docker commit的操作,提交一个新的镜像。
d.Docker再基于刚提交的新镜像,运行一个容器。
e.执行Dockerfile中的下一条指令。直到所有指令执行完毕。
(3)Dockerfile使用 # 号进行注释。
(4)Dockerfile官方文档:https://docs.docker.com/engine/reference/builder/
FROM: 指定基础镜像,后续指令操作将基于该镜像。
MAINTAINER:指定镜像作者及联系方式。
RUN: 在当前镜像中运行的命令。
EXPOSE: 指定容器的端口。
3、docker build构建新镜像
Dockerfile编写好后,就可以结合 docker build
构建新镜像了。
# sudo docker build -t static_web:v1 /tmp/static_web/
说明:
(1)-t: 指定标签。
(2)/tmp/static_web/:告诉Docker 到该目录寻找Dockerfile。
如果构建文件名不叫Dockerfile,例如:df。那么需要使用 -f
参数。示例:
# sudo docker build -t static_web:v1 /tmp/static_web/df
4、docker history
如果我们想要查看镜像是如何构建出来的,可以使用 docker history
命令。
# docker history static_web:v1
IMAGE CREATED CREATED BY SIZE COMMENT
637238913845 16... /bin/sh -c #(nop) ... 0B
d561441b8649 16... /bin/sh -c echo 'H... 28B
3457c54a2eda 16... /bin/sh -c apt-get... 87.9MB
775349758637 6 ... /bin/sh -c #(nop) ... 0B
5、从新镜像启动容器
# sudo docker run -d --name static_web -p 80 static_web:v1 nginx -g "daemon off;"
ac66082d8745fcbd0dcd77b1024499d4e701090228f477df085627505d09467f
说明:
(1)-p: 控制Docker在运行时公开哪些端口给外部(宿主机)。
(2)-P:也可以通过 -P
(大写的P)参数对外公开EXPOSE命令指定的端口。
# sudo docker run -d --name nginx1 -P static_web:v1 nginx -g "daemon off;"
(3)Docker 有两种方式将开发的端口映射到宿主机上。
a.随机选择。在让Docker自己在创建容器的时候随机选择一个位于32768-61000中的端口映射到容器的80端口。
b.指定端口。在创建容器的时候指定一个具体的端口映射到容器的80端口。
# sudo docker run -d --name nginx1 -p 8080:80 static_web:v1 nginx -g "daemon off;"
如上所示,将容器的80端口绑定到宿主机的8080端口。然后通过绑定的端口即可访问容器,如: http://127.0.0.1:8080
。
(4)可以通过 docker port
命令查看端口的映射情况
# sudo docker port static_web
80/tcp -> 0.0.0.0:32771
将镜像推送到Docker Hub
1、确保仓库名规范
如我在Docker Hub上的用户为sweeneys, 那么我的镜像仓库名应该为sweeneys/xxx的形式:
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
sweeneys/static_web latest e9ae1570fdba 46 minutes ago 152MB
static_web v1 e9ae1570fdba 46 minutes ago 152MB
apache2 latest bd1e81d3fd76 7 hours ago 188MB
redis latest dcf9ec9265e0 3 weeks ago 98.2MB
ubuntu 18.04 775349758637 6 weeks ago 64.2MB
ubuntu latest 775349758637 6 weeks ago 64.2MB
如上所示,只有 sweeneys/static_web
这个仓库名才是规范的。
2、docker login
推送镜像之前,要先登录Docker Hub账号。
# docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: sweeneys
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
3、docker push
推送镜像到Docker Hub使用的命令是 docker push
。
# docker push sweeneys/static_web
The push refers to repository [docker.io/sweeneys/static_web]
456ff9508bd5: Pushed
c142f1f70838: Pushed
e0b3afb09dc3: Pushed
6c01b5a53aac: Pushed
2c6ac8e5063e: Pushed
cc967c529ced: Pushed
latest: digest: sha256:949fe9adeedc001db1abb0d69ca138bc205b2d23c41b82d434fd9a21ec67f6a2 size: 1571
4、查看推送的镜像
最后可以到 https://hub.docker.com/ 查看我们推送的镜像。
参考资料
[1]James Turnbull, 《第一本Docker书》
[2]