基础概念
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容器启动时执行的命令。ENTRYPOINT
在docker 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
来帮助判断,其Dockerfile
的HEALTHCHECK
可以这么写:
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"
}
]
}
和CMD
、NETRYPOINT
一样,HEALTHCHECK
指令只可以出现一次,如果有多个HEALTHCHEC
K指令,那么只有最后一个才会生效!!!
ONBUILD
ONBUILD
是一个特殊的指令,它后面跟着的是其他指令,比如COPY
、RUN
等,而这些命令在当前镜像被构建时,并不会被执行。只有以当前镜像为基础镜像去构建下一级镜像时,才会被执行。格式为: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
命令查看所有镜像,如果存在 REPOSITORY
为 nginx
和 TAG
是 v1
的信息,就表示构建成功。
接下来使用 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]