官方文档:https://docs.docker.com/engine/reference/run/
Docker 是一个开源的应用容器引擎。 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
Docker的应用场景
Docker 的优点
这里主要是在Centos上安装,由于6.x版本的Centos上的docker版本太低,很多镜像都不支持,所以强烈推荐在7.x版本的Centos上安装。
直接使用yum安装就行(6.x版本是docker-io):
yum -y install docker-ce
安装完成后查看版本:
docker -v
systemctl start docker # 启动docker(6.x没有systemctl, 是service)
systemctl stop docker # 停止docker
systemctl status docker # 查看docker状态
要运行一个docker容器,首先需要镜像(image),镜像可以从官方拉取,也可以通过其他人给与的压缩包加载获得。
我们以apache httpd服务为例:
① 拉取镜像
官方拉取:docker pull httpd
② 查看拉取的镜像
docker images
③ 打包和加载镜像(这样就可以直接给别人用,不用pull了)
docker save –o httpd_bak.tar httpd # 把httpd镜像打包成httpd_bak.tar
docker load –i httpd_bak.tar # 加载httpd_bak.tar
④ 如果你想把image上传拿到自己的私有仓库或者docker hub,可以:
docker tag httpd xxx/httpd:<tag名字> # 建议push前给自己的镜像价格标签,xxx是你自己的私有仓库名称或者docker hub 账号名称
docker push xxx/httpd:<tag 名字> # push
① 运行image
docker run -d --name=my-apache-app -p 18000:80 -v /home/automation/bst-autotest/report:/usr/local/apache2/htdocs/ httpd
参数说明:
② 查看容器状态
docker ps # 查看活的容器的状态
docker ps -a # 查看所有的容器的状态,包括停止,死了的
③ 停止,启动,重启容器
docker stop <容器ID>或<容器名字>
docker start <容器ID>或<容器名字>
docker restart <容器ID>或<容器名字>
④ 查看容器详细信息
docker inspect <容器ID>或<容器名字>
⑤ 查看容器log
docker logs <容器ID>或<容器名字>
docker容器运行起来后,我们可以通过exec指令进入镜像内部
docker exec –it <容器ID>或<容器名字> /bin/bash
-it: 这个参数必须要,不然进不去bash目录。
如果不加-it,只是执行了下后面的命令
docker exec my-apache-app /bin/echo aa
Docker容器跑起来后,如果该容器暴露了端口并映射到宿主机,那么我们可以通过宿主机+端口来访问。
localhost:18000
① 删除容器,删除前需要停止容器(死了的,退出了的就不用了)
docker rm <容器ID>或<容器名字>
② 删除镜像(有的镜像删除不了,可能是容器正在使用或者有其他镜像依赖,前一种需要删除容器,后一种要先删除依赖)
docker rmi <镜像ID>
Dockerfile是用来定制镜像的,又时候官方的镜像不能满足我们的使用,这时候就需要我们定制了。
例如,jenkins官方的镜像没有安装vim,时区也不能设置,我需要定制下:
下面就是Dockerfile的文件内容,编辑完保存后,运行命令:
Docker build –t <取个镜像名字> . # .就是当前Dockerfile所在目录
链接:https://docs.docker.com/engine/reference/builder/#usage
Usage:
一般为docker build -t .
这个.的意思是会把当前目录下的所有内容加载到docker后台
可以用-f参数使用其他目录的Dockerfile:
$ docker build -f /path/to/a/Dockerfile .
-t参数可以指定为<image名字>:<tag>
$ docker build -t shykes/myapp .
也可以多个名字:
$ docker build -t shykes/myapp:1.0.2 -t shykes/myapp:latest .
build开始时会检查指令的语法正确否:
$ docker build -t test/myapp . Sending build context to Docker daemon 2.048 kB Error response from daemon: Unknown instruction: RUNCMD
注意:每个指令时独立的,会形成一个新的容器,例如命令RUN cd /tmp 就不会影响下一个指令
escape(转义)
有两种\和`(键盘1把旁边那个点)
一般windows用`,例如下面的:
FROM microsoft/nanoserver COPY testfile.txt c:\RUN dir c:\
执行:
PS C:\John> docker build -t cmd . Sending build context to Docker daemon 3.072 kB Step 1/2 : FROM microsoft/nanoserver ---> 22738ff49c6d Step 2/2 : COPY testfile.txt c:\RUN dir c: GetFileAttributesEx c:RUN: The system cannot find the file specified. PS C:\John>
由于windows的路径包含\,而\又是转义,上面的就是转义了换行,所以最好用`(开头声明用`来表示转义):
# escape=` FROM microsoft/nanoserver COPY testfile.txt c:\ RUN dir c:\
Environment replacement
使用ENV xxx来声明,可以用在整个Dockerfile中,$variable_name和${variable_name}都可以
例如:
FROM busybox ENV foo /bar WORKDIR ${foo} # WORKDIR /bar ADD . $foo # ADD . /bar COPY \$foo /quux # COPY $foo /quux
FROM
FROM <image>[:<tag>] [AS <name>]
FROM前只能有ARG,而且这个ARG只能FROM用,例如:
ARG CODE_VERSION=latest FROM base:${CODE_VERSION} CMD /code/run-app
如果FROM后面的要使用,请后面再添加ARG:
ARG VERSION=latest FROM busybox:$VERSION ARG VERSION RUN echo $VERSION > image_version
RUN
两种格式:
RUN <command>
RUN ["executable", "param1", "param2"]
RUN会在当前的层数执行并提交结果,并且结果可以供下一步使用。
CMD
ENTRYPOINT
LABEL
LABEL <key>=<value> <key>=<value> <key>=<value> ...
Label指令给image添加元数据,build完后可以使用docker inspect进行查看,例如:
LABEL "com.example.vendor"="ACME Incorporated" LABEL com.example.label-with-value="foo" LABEL version="1.0" LABEL description="This text illustrates \ that label-values can span multiple lines."
---------docker inspect------------------
"Labels": { "com.example.vendor": "ACME Incorporated" "com.example.label-with-value": "foo", "version": "1.0", "description": "This text illustrates that label-values can span multiple lines.", "multi.label1": "value1", "multi.label2": "value2", "other": "value3" },
MAINTAINER (deprecated)
MAINTAINER <name>
作者,现在可以用LABEL代替,例如:
LABEL maintainer="SvenDowideit@home.org.au"
EXPOSE
EXPOSE <port> [<port>/<protocol>...]
暴露端口,在Dockerfile里只是记录下这个image需要暴露的端口,实际用的话还是需要run的时候-p指定:
EXPOSE 80/tcp EXPOSE 80/udp
docker run -p 80:80/tcp -p 80:80/udp ...
ENV
ENV <key> <value> ENV <key>=<value> ...
给Dockerfile后面的指令使用,多个ENV写一行:
ENV myName="John Doe" myDog=Rex\ TheDog \ myCat=fluffy
ADD
ADD [--chown=<user>:<group>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"] (this form is required for paths containing whitespace)
--chown只支持linux
ADD 指令copy新文件,目录,远程文件从src到dest
ADD支持通配符,例如:
ADD hom* /mydir/ # adds all files starting with "hom" ADD hom?.txt /mydir/ # ? is replaced with any single character, e.g., "home.txt"
<dest>需要是一个绝对路径,或者关联WORKDIR下的路径,例如:
ADD test relativeDir/ # adds "test" to `WORKDIR`/relativeDir/ ADD test /absoluteDir/ # adds "test" to /absoluteDir/
ADD遵守以下规则:
1. <src>必须在build的上下文环境中,你不能:
ADD ../something /something 因为docker build第一步会发送路径到docker守护进程
2. <src>是一个URL,<dest>不以/结束,那么src的文件将会下载到dest
3. <src>是一个URL,<dest>不以/结束,那么src会将会下载成<dest>/<filename>例如:
ADD http://example.com/foobar / 将会创建文件/foobar <src>的URL要指定详细的文件地址,不能这么写:
4. <src>如果是个目录,那么所有的文件都会被copy(目录并不会被copy,只有底下的所有东西)
5. <src>如果是压缩文件,那么会解压成目录
6. <dest>不以/结束,那么会把src的文件内容会写到dest里面(不是dest/下)
7. 如果<dest>不存在,那么它会把目录一块儿创建在当前WORKDIR下
COPY
COPY [--chown=<user>:<group>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"] (this form is required for paths containing whitespace)
COPY和ADD的区别就是不能解压压缩文件。
VOLUME
VOLUME ["/data"]
可以是:VOLUME ["/var/log/"] 或者 VOLUME /var/log /var/db
Docker run会基于volume下的数据在base image上面初始化。例如:
FROM ubuntu RUN mkdir /myvol RUN echo "hello world" > /myvol/greeting VOLUME /myvol
这里,docker run 会在/myvol创建一个挂载卷,然后把greeting文件copy到里面。注意后面的Dockerfile如果对greeting或者再建新文件都会被抛弃掉。
USER
USER <user>[:<group>] or
USER <UID>[:<GID>]
给RUN,CMD,ENTRYPOINT,COPY使用的账号。
WORKDIR
WORKDIR /path/to/workdir
工作目录,RUN,CMD,ENTRYPOINT,COPY都会使用到。
WORKDIR 可被使用多次:
WORKDIR /a WORKDIR b WORKDIR c RUN pwd
实际上pwd会是/a/b/c
ARG
ARG <name>[=<default value>]
docker build的时候用参数--build-arg <varname>=<value>给ARG传递值,而且是声明的时候才生效。例如:
1 FROM busybox 2 USER ${user:-some_user} 3 ARG user 4 USER $user ...
然后:$ docker build --build-arg user=what_user .
那么实际上:
第二行 user 是 some_user(:-的意思是如果不存在值那么用-后面的,反之如果是:+如果存在后面的那么留空)
第三行 定义了ARG
第四行 user 是 what_user
原文:https://www.cnblogs.com/lopezauto/p/10773173.html