Docker

基础概念

Image(镜像)

即,镜像文件,可以还原出同样功能的文件副本。
例如: 我们常接触的熟悉的 电脑的操作系统,需要使用 保存着操作系统镜像文件的光盘/U盘/硬盘 把 操作系统 安装到电脑主机中,然后开机 运行起来的 才是真正的 操作系统
docker image 也是同样的道理, 是用来启动容器的只读的镜像文件。

Container(容器)

启动一个镜像就是一个容器,容器是在当前linux系统创建一个隔离环境,多个容器之间不会相互影响,保证容器中的程序运行在一个相对安全的环境中。

Repository(仓库)

即,共享和管理Docker镜像的仓库

Docker常用命令

查看 docker 版本或信息

    docker version
    # 或者
    docker info

docker 服务管理

启动

    # service 命令的用法
    sudo service docker start # 启动docker服务
    sudo service docker stop # 停止docker服务
    sudo service docker restart # 重启docker服务

    # systemctl 命令的用法
    sudo systemctl start docker # 启动docker服务
    sudo systemctl stop docker # 停止docker服务
    sudo systemctl restart docker # 重启docker服务

镜像相关命令

列出本地的镜像

docker images # 等同于 docker image ls

输出内容列的含义:

  • REPOSITORY:镜像所属仓库名称。
  • TAG:镜像标签。默认是 latest,表示最新。
  • IMAGE ID:镜像 ID,表示镜像唯一标识。
  • CREATED:镜像创建时间。
  • SIZE: 镜像大小。

搜索镜像

docker search命令搜索存放在 Docker Hub(这是docker官方提供的存放所有docker镜像软件的地方,类似maven的中央仓库)中的镜像。

docker search 关键词

输出内容列的含义:

  • NAME:镜像仓库名称。
  • DESCRIPTION:镜像仓库描述。
  • STARS:镜像仓库收藏数,表示该镜像仓库的受欢迎程度,类似于 GitHub的 stars0
  • OFFICAL:表示是否为官方仓库,该列标记为[0K]的镜像均由各软件的官方项目组创建和维护。
  • AUTOMATED:表示是否是自动构建的镜像仓库。

拉取docker镜像

拉取一个镜像,需要指定Docker Registry的地址和端口号,默认使用官方仓库Docker Hub
需要指定仓库名和标签,仓库名由作者名和软件名组成,标签默认使用latest,仓库名和标签唯一确定一个镜像。

docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]

拉取非官方的第三方镜像,需要指定完整仓库名,例如:

docker pull mysql/mysql-server:latest

删除本地镜像

如果有使用该镜像创建的容器未删除,则不允许删除镜像。加上-f,强制删除

    # docker rmi <=> dockere image rm

    docker rmi <镜像ID>

    # 删除全部image -f: 强制删除
    docker rmi [-f] $(docker images -q)

    # 删除所有不使用的镜像
    docker image prune -f -a # 等同于 docker image prune --force --all

容器相关命令

查看容器

    # docker  ps <=> docker container ls
    docker  ps  # 正在运行的容器
    docker  ps -a # 列出所有的容器(包括未运行的)
    docker  ps -aq # 列出所有的容器(包括未运行的)ID
    docker  inspect <容器ID>/<容器名称> # 查看容器信息

输出内容列含义:

  • CONTAINER_ID:表示容器 ID。
  • IMAGE:表示镜像名称。
  • COMMAND:表示启动容器时运行的命令。
  • CREATED:表示容器的创建时间。
  • STATUS:表示容器运行的状态。UP表示运行中, Exited表示已停止。
  • PORTS:表示容器对外的端口号。
  • NAMES:表示容器名称。该名称默认由 Docker自动生成,也可使用 docker run命令的–name选项自行指定的名称。

新建并启动容器
先检查本地是否存在指定镜像。如果本地不存在该名称的镜像,Docker就会自动从Docker Hub下载镜像并启动容器。

docker run <镜像ID>/<镜像名>

常用的选项

  • -d 后台运行(守护进程形式)

  • -p 宿主机端口:容器端口 #开放容器端口到宿主机端口

  • -i --interactive=true|false 默认是 false: 开启交互式

  • -t --tty=true | false 模式 false :开启终端

  • –name 自定义容器名称

  • -v [宿主机目录]:<容器目录>:[rw|ro]

    • 宿主机目录如果不存在,则会自动生成
    • 宿主机目录为相对路径,则会自动生成/var/lib/docker/volumes/相对路径/_data
    • 省略宿主机目录,只写一个目录名,则会自动生成/var/lib/docker/volumes/随机名称/_data,写出来的目录名做为容器内目录名
    • rw 容器可读写挂载的目录,ro 容器只能读挂载的目录
  • –privileged

    • 以特权方式启动容器,防止容器内操作宿主机目录 报“Permission denied”
  • –restart 开机自动启动Docker容器

    • no - 容器退出时,不重启容器;
    • on-failure[:尝试重启次数] - 只有在非0状态退出时才从新启动容器;
    • always - 无论退出状态是如何,都重启容器;
  • –net 网络配置参数

    • –net选项:指定网络模式,该选项有以下可选参数:
    • –net=bridge:默认选项,表示连接到默认的网桥。
    • –net=host:容器使用宿主机的网络。
    • –net=container:NAME-or-ID:告诉 Docker让新建的容器使用已有容器的网络配置。
    • –net=none:不配置该容器的网络,用户可自定义网络配置。

例子:

    # 启动一个Nginx容器。通过 http://Docker宿主机IP:91/ 访问。
    docker run -d -p 91:80 nginx

    # 开启终端交互式
    docker run -it xxx /bin/base

    # 自定义容器名称
    docker run --name sayhello -it  xxx /bin/bash

    # 注意,这里的容器名字叫:mysql5.7-master-node-01,mysql的root用户密码是:123456,映射宿主机子的端口3406到容器的端口3306,仓库名mysql和标签(tag)唯一确定了要指定的镜像
    docker run --name mysql5.7-master-node-01 -p 3406:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7

容器重命名

docker rename 旧名称 新名称

容器跟着docker启动而启动

# docker container update
docker update --restart=always 容器名字

复制文件

    # docker  cp <=> docker container cp
    
    # 从容器到宿主机复制
    # docker  cp <容器ID>/<容器名称>:容器路径       宿主机路径         
    docker cp tomcat:/webapps/js/text.js /home/admin

    # 从宿主机到容器复制
    #docker cp 宿主路径中文件      <容器ID>/<容器名称>:容器路径   
    docker cp /home/admin/text.js tomcat:/webapps/js

容器 启动、停止、重启、杀死、删除

    # 启动(已停止)的容器
    docker start  [-i] <容器ID>/<容器名称>
    
    # 启动所有容器
    docker start $(docker ps -a | awk '{ print $1}' | tail -n +2)

    # 停止容器
    # docker stop <=> docker container stop
    docker stop <容器ID>/<容器名称>

   # 停止所有容器
   docker stop $(docker ps -a | awk '{ print $1}' | tail -n +2)

    # 重启
    docker restart <容器ID>/<容器名称>

    # 强制停止容器(发送 SIGKILL信号来强制停止容器)
    docker kill <容器ID>/<容器名称>

    # 以守护进程形式继续运行容器
    ctrl + p ctrl + q

    # 删除容器 docker container rm
    # docker rm <=> docker container rm
    docker rm <容器ID>/<容器名称>

    # 删除所有容器
    docker rm $(docker ps -aq)

    # 删除所有停止的容器
    docker container prune

	
	#清除镜像列表名称为<none>的无名镜像(这是因为我们上传了名称相同的镜像,docker会把名称赋值给我们较新的镜像,原先较旧的镜像也不会覆盖,而是会变为一个无名镜像)
	docker rmi $(docker images | grep "none" | awk '{print $3}')

进入容器

用于进入一个正在运行的docker容器。如果docker run命令运行容器的时候,没有使用-it参数,就要用这个命令进入容器。一旦进入了容器,就可以在容器的 Shell 执行命令了

docker exec -it <容器ID>/<容器名称> /bin/bash

进入容器

docker attach <容器ID>/<容器名称>,已过时的命令,退出会导致容器停止,推荐使用docker exec来实现相同的功能。

查看容器日志

    docker logs <容器ID>/<容器名称> # 等同于 docker container logs <容器ID>/<容器名称>

    docker logs [-f] [-t] [ --tail] <容器ID>/<容器名称>
    # -f   --follows=true|false 默认为 false
    # -t   --timestamps=true| false 默认为 false
    #  --tail =“all"

清空容器的日志

$(docker inspect --format='{{.LogPath}}' <容器ID或容器名>)

查看容器内的进程

docker top <容器ID>/<容器名称>

在运行的容器中启动新的进程

docker exec [-d] [-i] [-t] 容器名称 [command] [args….]

停止守护进程形式容器

    docker  stop <容器ID>/<容器名称>
    docker  kill   <容器ID>/<容器名称>

Dockerfile常用的指令

这部分内容,主要参考来源

Dockerfile是一个文本文件,其中包含了若干条指令,指令描述了构建镜像的细节,DockerFile的每一个指令都会新建一个镜像层。

指令格式:
INSTRUCTION argument # INSTRUCTION不分大小写,推荐大写

FROM

FROM 是用于指定构建使用的基础镜像。同一个 Dockerfile中可以多次使用 FROM 创建多个镜像。不以任何镜像为基础的写法FROM scratch

指令语法:

    FROM <image>
    FROM <image>:<tag>
    FROM <image>:<digest>

eg:

FROM nginx #从本地的镜像仓库里拉取ngxin的docker镜像
FROM mysql:5.7

RUN
运行指定的命令,只在docker build时执行。每个 RUN 指令会在原有的镜像基础上添加了一个改动层,原有的镜像不会有变化。尽量把需要执行的多个shell命令 用一个RUN指令完成。

指令语法:

RUN <command>

eg:

RUN yum update && yum install openjdk-8-jdk -y && yum clean all

COPY

复制本地主机的 <源路径> (Dockerfile 所在目录的相对路径,只能是本地主机的)的文件或文件夹到容器中的 <目标路径>。当使用本地目录为源目录时,推荐使用 COPY 。

指令语法:

COPY <源路径> <目标路径>

eg:

    COPY . /app
    COPY app.tar.gz /app
    # 源路径可以是多个,甚至是通配符,其通配规则只需要满足GO语言的filepath.Math规则即可
    COPY ./test1.py ./test2.py /test/
    COPY ./t*.py /test/
    COPY ./test?.py /test/

ADD

添加文件,把本地主机的<源路径>的文件或文件夹复制到容器<目标路径>,<源路径>可以是Dockerfile所在目录的相对路径,也可以是一个URL的链接,还可以是压缩文件。

指令语法:

ADD <源路径> <目标路径>

eg:

    ADD nginx.conf /etc/nginx/nginx.conf
    ADD app.tar.gz /app/app
    # 远程URL,Docker引擎会自动帮我们将远程URL的文件下载下来到目标路径下
    ADD http://192.168.0.89:5000/test.py /test/
    
    # 压缩格式为gzip、bzip2以及xz的情况下,ADD指令都会将其解压缩
    ADD docker2.tar /test/

非常值得注意的是,目标路径为一个URL时,会将其自动下载到目标路径下,但是其权限被自动设置成了600,如果这并不是你想要的权限,那么你还需要额外增加一层RUN命令进行更改,如果下载的是一个压缩包,同样你还需要额外增加一层RUN命令进行解压缩。
所以,使用ADD指令下载文件,还不如指定只用一层RUN,使用curl或者wget工具进行下载,并更改权限,然后进行解压缩,最后清理无用文件!

当你的源路径为压缩文件并且不想让Docker引擎将其自动解压缩,这个时候就不可以使用ADD命令,你可以使用COPY命令进行完成!

其实ADD命令并不实用,并不推荐使用!!!

CMD

设置启动容器时默认执行的命令(docker run 或者 docker start),CMD指令可以包含可执行文件。如果不包含可执行文件 就要用 ENTRYPOINT 指定一个,然后 CMD 指令的参数就会作为ENTRYPOINT的参数。如果一个Dockerfile里面有多条CMD指令,最后一个生效。
设置了CMD指令后,在执行 docker run 的时候如果指定要执行的命令会覆盖掉 Dockerfile 中的 CMD 指令。

指令语法有三种格式:

    CMD ["可执行文件","参数1","参数2",...] #推荐使用 exec 形式。
    CMD ["参数1","参数2"] #无可执行程序形式
    CMD command 参数1 参数2 #shell 形式(默认调用 /bin/sh -c 执行命令)。

启动 /app:CMD ["app.py"]

docker run 时,指定要执行的命令会覆盖掉 Dockerfile 中的 CMD 指令。

    # Dockerfile
    FROM ubuntu
    CMD ["echo", "Hello Docker!"]

我们将其构建成成镜像ubuntu:v1.1,下面,我们以此镜像为基础创建并启动一个容器,如下:

docker run -it ubuntu:v1.1 cat /etc/os-release

那么容器只会执行cat /etc/os-release命令,也就是说在控制台只会输出系统版本信息,并不会输出’Hello Docker!’。

ENTRYPOINT

容器入口,和CMD指令的目的一样,设置Docker容器启动时执行的命令。ENTRYPOINTdocker run命令中同样也可以进行指定(需要指定--entrypoint参数)。
docker run时指定了--entrypoint参数,会覆盖Dockerfile中ENTRYPOINT的指令。一个 Dockerfile 中如果有多个ENTRYPOINT,最后一个生效。

ENTRYPOINT 命令也有两种格式:

ENTRYPOINT ["executable", "param1", "param2"] #推荐使用 exec形式
ENTRYPOINT command param1 param2 #shell 形式

eg:

ENTRYPOINT ["python"]

当指定了ENTRYPOINT指令时,CMD指令里的命令性质将会发生改变!CMD指令中的内容将会以参数形式传递给ENTRYPOINT指令中的命令,如下:

FROM ubuntu
ENTRYPOINT ["rm", "docker2"]
CMD ["-rf"]

其实,它真正执行的命令将会是:

rm docker2 -rf

上面的例子,完全可以使用一条CMD指令CMD ["rm", "docker2", "-rf"]来完成。这两个指令到底有什么区别,为什么要同时保留这两条指令呢?

我们可以使用ENTRYPOINT指令和CMD指令相结合,使得在创建并启动时要执行的命令更加灵活!有如下Dockerfile:

FROM ubuntu
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["curl", "-s", "http://ip.cn"]

此时,我们将其构建成镜像ubuntu:v1.2,下面我们创建并启动容器:

docker run -it ubuntu:v1.2

将会在控制台输出我们相应的公网IP信息!此时,如果我们还需要获取HTTP头信息时,我们可以这样:

docker run -it ubuntu:v1.2 -i

此时,将会在控制台中将公网IP信息以及HTTP头信息全部输出!我们知道,docker run命令中紧跟在镜像后面的是CMD指令命令,运行时会替换默认的CMD指令。因为我们在Dockerfile中指定了ENTRYPOINT指令,根据ENTRYPOINT指令的特性知道,当指定了ENTRYPOINT指令,CMD指令的内容将会以参数的形式传递给ENTRYPOINT,所以在容器中最终执行的命令是curl -s -i http://ip.cn,-i参数被传递到ENTRYPOINT中,所以最终在控制台中会输出HTTP头信息!!!

EXPOSE

设置容器运行时对外开放的端口。

指令语法:

EXPOSE <port> [<port>...]

eg:

EXPOSE 80

WORKDIR

WORKDIR 用于配合 RUN,CMD,ENTRYPOINT 命令设置容器的工作路径。,可以在构建镜像的时候使用,也可以在启动容器的时候使用,构建使用是通过WORKDIR将当前目录切换到指顶目录中,可以理解为shell的cd,启动容器的时候使用的意思为 docker run 启动容器时,默认进入到目录是WORKDIR 指定的。可以设置多次,如果是相对路径,则相对前一个 WORKDIR 命令。默认路径为/。WORKDIR指令可以通过docker run命令中的-w参数来进行覆盖。

指令语法:

WORKDIR /path/to/workdir

eg:

WORKDIR /usr/local/nginx
WORKDIR /app

ENV

设置环境变量,可以是在构建镜像时使用,也可以在运行中的容器使用。

指令语法:

ENV <key> <value>

ARG

构建参数,只在镜像构建时有效的环境变量。与ENV指令生命周期不同。但是不要因此就用ARG来保存密码之类的信息,因为通过docker history还是能够看得到的。ARG指令与ENV指令的使用类似.

eg:

    FROM ubuntu:16.04
    ARG app="python-pip"
    RUN apt-get update && apt-get install -y $app && rm -rf /var/lib/apt/lists/*

ARG构建参数可以通过docker run命令中的–build-arg参数来进行覆盖。

USER

USER指令用于将会用以什么样的用户去运行,例如:

FROM ubuntu:16.04
USER docker

基于该镜像启动的容器会以docker用户的身份来运行,我们可以指定用户名或者UID,组名或者GID,或者两者的结合。USER指令可以在docker run命令中的-u参数进行覆盖。

eg:

FROM ubuntu:16.04
USER user
USER user:group
USER uid
USER uid:gid
USER user:gid
USER uid:group

VOLUME

设置容器挂载数据卷,容器运行时应尽量保持容器内不发生任何写入操作,对于需要保存动态数据的应用,其数据文件应该将其保存在数据卷中(VOLUME)

指令语法:

VOLUME <路径>
VOLUME ["<路径>","<路径>",...]

eg:

    VOLUME /data/
    VOLUME ["/data","/command"]

这里的/data和/command目录在容器运行时会自动挂载为匿名卷,任何向/data和/command目录中写入的信息都不会记录进容器存储层,从而保证了容器存储层的无状态化!容器匿名卷目录指定可以通过docker run命令中指定-v参数来进行覆盖

HEALTHCHECK

HEALTHECHECK指令是告诉Docker该如何判断容器的状态是否正常,这是1.12引入的新指令,其格式有两种:

HEALTHCHECK [options] CMD <命令>:检查容器健康状态的命令
HEALTHCHECK NONE:如果基础镜像有健康检查指令,这一行将会屏蔽掉其健康检查指令

HEALTHECHECK支持下列选项:

  • –interval=<间隔>:两次检查的时间间隔,默认为30s
  • –timeout=<时长>:健康检查命令运行超时时间,如果超过这个时间,本次健康检查将会判定为失败,默认为30s
  • –retries=<次数>:当连续失败指定次数之后,则将容器状态视为unhealthy,默认为3次

在没有HEALTHCHECK指令之前,Docker引擎只可以通过容器内主进程是否退出来判断容器状态是否异常。很多情况下这没有问题,但是如果程序进入了死锁状态,或者死循环状态,应用进程并不退出,但是该容器已经无法继续提供服务了。在1.12之前,Docker引擎不会检测到容器的这种状态,从而不会重新调度,导致可能容器已经无法提供服务了却仍然还在接收用户的请求。

假设我们有个镜像是最简单的Web服务,我们希望增加健康检查来判断Web服务是否在正常工作,我们可以用curl来帮助判断,其DockerfileHEALTHCHECK可以这么写:

FROM nginx
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
HEALTHCHECK --interval=5s --timeout=3s CMD curl -fs http://localhost/ || exit 1

接下来,我们将该Dockerfile编译构建成一个镜像,并以此镜像为基础创建并启动一个容器。此时,我们使用docker container ls命令来查看容器的状态,如下:

root@ubuntu:~/docker# docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                   PORTS                NAMES
036b91eea00d        nginx:v1.2          "nginx -g 'daemon of…"   7 seconds ago       Up 6 seconds (healthy)   0.0.0.0:80->80/tcp   web

我们再STATUS这一列中可以看到,状态未healthy。如果我们快速的多次执行docker container ls的话,会发现STATUS状态是由health: starting最后变为healthy,当然如果容器未在正常工作,最后的状态将会变为unhealthy

这里,我们设置了每5s检查一次,如果检查时间超过3s没有响应就视为失败。||符号左边的命令执行结果为假,右边的命令才会执行!

为了帮助排除故障,健康检查命令的输出会被存储于健康状态里,我们可以使用docker inspect命令来进行查看:

root@ubuntu:~/docker# docker inspect --format '{{json .State.Health}}' web | python3 -m json.tool
{
    "Status": "healthy",
    "FailingStreak": 0,
    "Log": [
        {
            "Start": "2018-07-17T21:15:05.900643297+08:00",
            "End": "2018-07-17T21:15:05.968989028+08:00",
            "ExitCode": 0,
            "Output": "<!DOCTYPE html>\n<html>\n<head>\n<title>Welcome to nginx!</title>\n<style>\n    body {\n        width: 35em;\n        margin: 0 auto;\n        font-family: Tahoma, Verdana, Arial, sans-serif;\n    }\n</style>\n</head>\n<body>\n<h1>Welcome to nginx!</h1>\n<p>If you see this page, the nginx web server is successfully installed and\nworking. Further configuration is required.</p>\n\n<p>For online documentation and support please refer to\n<a href=\"http://nginx.org/\">nginx.org</a>.<br/>\nCommercial support is available at\n<a href=\"http://nginx.com/\">nginx.com</a>.</p>\n\n<p><em>Thank you for using nginx.</em></p>\n</body>\n</html>\n"
        }
    ]
}

CMDNETRYPOINT一样,HEALTHCHECK指令只可以出现一次,如果有多个HEALTHCHECK指令,那么只有最后一个才会生效!!!

ONBUILD

ONBUILD是一个特殊的指令,它后面跟着的是其他指令,比如COPYRUN等,而这些命令在当前镜像被构建时,并不会被执行。只有以当前镜像为基础镜像去构建下一级镜像时,才会被执行。格式为:ONBUILD <其他指令>

Dockerfile中的其他指令都是为了构建当前镜像准备的,只有ONBUILD指令是为了帮助别人定制而准备的。例如:

from ubuntu:16.04
WORKDIR /data
ONBUILD RUN mkdir test

此时,我们以此Dockerfile进行构建镜像ubuntu:test,并以此镜像为基础创建并启动一个容器,进入容器后,容器会自动切换到WORKDIR指令下的目录,此时我们使用ls命令会发现在工作目录下,并未创建test文件夹,如下:

root@ubuntu:~/docker# docker run -it ubuntu:test
root@3a8f912fd23b:/data# ls
root@3a8f912fd23b:/data#

此时,我们再创建一个Dockerfile,只需一个FROM指令即可,使其继承刚刚我们构建的ubuntu:test镜像,如下:

FROM ubuntu:test

我们再以此Dockerfile构建镜像ubuntu:test_onbuild,并以此镜像为基础创建并启动一个容器,进入容器后,容器会自动切换到WORKDIR指令下的目录,此时我们使用ls命令会发现在工作目录下,已经创建好了一个名为test的文件夹,如下:

root@ubuntu:~/docker# docker run -it ubuntu:test_onbuild
root@5394e605b6ea:/data# ls
test

LABEL

LABEL指令可以为镜像指定标签,其格式为:LABEL <key1>=<value1> <key2>=<value2> ...

LABEL后面是键值对,多个键值对以空格进行隔开,如果value中包含空格,请使用""将value进行圈起来,如下:

FROM ubuntu:16.04
LABEL name=test
LABEL description="a container is used to test"

我们知道,DockerFile的每一个指令都会新构建一层,所以,上面的LABEL我们可以写成一条指令,用空格进行隔开,如下:

FROM ubuntu:16.04
LABEL name=test description="a container is used to test"

为了美观,我们还可以使用\符号进行换行操作。

要查看镜像的标签,我们可以使用docker inspect命令,如下:

root@ubuntu:~# docker inspect --format '{{json .Config.Labels}}' test | python3 -m json.tool 
{
    "description": "a container is used to test",
    "name": "test"
}

其中“test”为容器名称!

值得注意的是,这里的标签并非是我们一开始将镜像名称中的<仓库>:<标签>,这两者是不一样的!这里标签,类似于签条,注解之类的意思

MAINTAINER

MAINTAINER 描述镜像创建者信息。已经被弃用,可以使用LABEL指令进行替代。

指令语法:

MAINTAINER <name>

eg:

MAINTAINER HelloWord <lzxingg@gmail.com>

Dockerfile 构建镜像demo1

以下是一个安装tomcat+jdk的dockerfile

# 引用一个centos为基础镜像
FROM centos:v1

# 将tomcat和jdk压缩包复制到/usr/local下
ADD jdk-8u60-linux-x64.tar.gz /usr/local
ADD apache-tomcat-6.0.53.tar.gz /usr/local

# 设置jdk的环境变量相当于更改/etc/profile文件
ENV JAVA_HOME /usr/local/jdk1.8.0_60
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME=/usr/local/apache-tomcat-6.0.53
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
 
# 暴露容器端口为8080
EXPOSE 8080

# 在docker run 的时候执行catalina.sh 来启动tomcat
CMD ["catalina.sh","run"]

Dockerfile 构建镜像demo2

构建Dockerfile
我们大体已经把Dockerfile的写法讲述完毕,我们可以自己动手写一个例子:

mkdir static_web && cd $_ && touch Dockerfile

编辑Dockerfile内容

FROM nginx
MAINTAINER docker_demo <lzxingg@gmail.com>
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html

Dockerfile文件所在目录执行:

docker build -t dockerdemo/nginx_web:v1 .

-t 是为新镜像设置仓库和名称,其中 dockerdemo 为仓库名, nginx_web 为镜像名, :v1为标签(不添加为默认 latest ), .是 Dockerfile的相对位置

我们构建完成之后,使用 docker images 命令查看所有镜像,如果存在 REPOSITORYnginxTAGv1 的信息,就表示构建成功。

接下来使用 docker run 命令来启动容器

docker run --name nginx_web -d -p 8080:80 dockerdemo/nginx_web:v1

这条命令会用 nginx 镜像启动一个容器,命名为 nginx_web ,并且映射了 8080 端口,这样我们可以用浏览器去访问这个 nginx 服务器:http://localhost:8080/ 或者 http://本机的IP地址:8080/

构建镜像

docker commit 通过容器构建(不推荐)

    docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
        -a, --author=“”         指定作者
        -m, --meaasge=“”     备注信息
        -p, --pause=true        Pause container during commit

docker build 通过 Dockerfile 文件构建(推荐)
    docker build [OPTIONS]  PATH | URL | -
        --force-rm = false
        --no-cache = false
        --pull = false
        -q,--quiet = false
        --rm = true
        -t,--tag = “”

推送

docker push NAME[:TAG]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值