Docker 概念、命令及Dockerfile介绍
# 1.docker 的概念,docker 是什么
docker 分为三种概念:镜像 容器 仓库
镜像:类似于一个模板,里面包含了一些内容
容器:容器是一个镜像的实例,如果理解镜像为一个 class,那么容器就被理解为是 new class (); 是镜像的实例
仓库:就是下载镜像资源的地方。
docker 容器不是虚拟机,容器可以说是一个进程,我们可以给容器分配内存。就像 windows 安装了虚拟机,可以给虚拟机分配内存大小,磁盘空间。
# 2.docker 基础命令
搜索镜像,从 maven 仓库中查询
docker search mysql
列出当前系统存在的镜像
docker images
给镜像更换名称
docker tag imageId repository:tag
删除镜像 (-f 强制) 必须知道镜像的 imageId
docker rmi -f imageId
repository:tag (镜像的仓库源:镜像的标签) 拉取
docker pull repository:tag
运行一个容器
docker run -it -d --name "xxx" -p port1:port2 -p port3:port4 -v home/data:/data repository:tag
- run:运行容器命令
- -it:运行后直接与终端交互,比如运行 jar 或其他应用的时候 查看他们的启动信息
- -d:后台运行
- -p port1:port2:端口映射 port1 (宿主机) port2 (容器) 容器的端口是可以重复的,所以容器和物理机的端口可以一致。rabbitmq 有两个端口 5672 和 15672 所以会用到双 -p repository:tag -> 如果不指定 tag,默认使用最新的
- --name "xxx":指定容器名称
- -v /home/data:/data:/home/data (宿主机):/data (容器) 本地地址和容器地址产生挂载关系, 在容器内部该目录下,或者宿主机内部该目录下,修改文件、创建文件,彼此都会同步修改
- --restart=always:总是运行,当重启 docker 后会自动运行起来
- repository:tag:指定运行镜像的名称
查看运行的容器
docker ps
查看所有状态的容器
docker ps -a
检查容器内部信息
docker inspect 容器名称|容器前12位id
停止容器
docker stop 容器名称|容器前12位id
开启容器运行
docker start 容器名称
删除容器之前必须先停止容器运行
docker rm 容器名称
查看容器日志
dokcer logs -f 容器id
进入容器内部
docker exec -it mysql bash# 进入mysql内部
mysql -uroot -p123456# 登录mysql服务 注意这里mysql -uroot -p123456 是连起来的
2
把一个容器制作为一个新的镜像
docker commit
-m="提交信息"
-a="作者"
容器id
自定义镜像名称:[自定义标签名]
2
3
4
5
查看容器的信息
docker inspect 容器ID
对于没有私有仓库的要使服务器间共享一个 docker 镜像,可以先把某台机器上的进行先导出,然后其他服务器在导入即可
# 导出
docker save
镜像ID
-o /本地路径/文件.tar 这句话意思导出到你宿主机的一个地址,文件名随便起后缀为tar,路径要提前建好
# 导入
docker load < /上传文件的地址/导出的文件名.tar
# 查看导入的镜像
docker images
2
3
4
5
6
7
8
9
10
容器之间共享,容器 2 共用 容器 1
docker tun -it
-- name 容器2
--volumes-from 容器1(容器1必须已启动)
镜像名称
2
3
4
查看制作镜像时叠加其他镜像的操作
docker history 镜像ID
# 3. 修改已经存在容器的端口
1、停止容器 (docker stop d00254ce3af7)
2、停止 docker 服务 (systemctl stop docker)
3、修改这个容器的 hostconfig.json 文件中的端口(原帖有人提到,如果 config.v2.json 里面也记录了端口,也要修改)
cd /var/lib/docker/containers/d00254ce3af7* # 这里是CONTAINER ID
vim hostconfig.json
如果之前没有端口映射, 应该有这样的一段:
"PortBindings":{}
增加一个映射, 这样写:
"PortBindings":{"8080/tcp":[{"HostIp":"","HostPort":"60000"}]}
前一个数字是容器端口, 后一个是宿主机端口。将宿主机的60000端口映射到容器的8080端口
2
3
4
5
6
7
8
9
4、启动 docker 服务 (systemctl start docker)
5、启动容器 (docker start d00254ce3af7)
# 4. 制作镜像的基本命令
# 概念
Dockerfile 默认会把当前所在文件的上下问都发送给 Docker Server,最终制作成一个镜像,比如你得 DockerFile 在 linux 的根 (/) 目录,那么就会递归根目录下的所有文件,发送到 Docker Server 制作镜像,所以制作 Dockerfile 最好是在某一个地方新建文件夹去制作。制作过程都是依赖于一个个的镜像,所以会有缓存加速下次制作,如果不需要依赖缓存 可以在命令制作的最后面加 --no-cache
.dockerIgnore 是用来忽略哪些文件或目录不参与到制作镜像中
制作命令: docker build -f /home/docker/nginx/Dockerfile .
-f 用来指定 Dockerfile 所在的位置,一般会使用 docker build -t nginx2 .
-t 在当前目录制作镜像, nginx2
镜像的名字, .
代表 Dockerfile 就在当前目录
# 命令
指令 | 描述 |
---|---|
FROM | 构建的新镜像是基于哪个镜像。例如:FROM centos:6,第一个指令必须是 FROM |
MAINTAINER | 镜像维护者姓名或邮箱地址。例如:MAINTAINER Mr.chen |
RUN | 构建镜像时运行的 Shell 命令。例如:RUN ["yum","install","httpd"] 也可以直接 RUN yum install httpd 或者 RUN yum install httpd |
CMD | 容器运行时执行的Shell命令 (编写的 dockerfile 中多个 cmd 都会执行,但默认保留最后一个命令,如果 docker run 运行时传递 command,会覆盖 cmd 的保留命令),启动容器会执行 CMD 的保留命令。例如:CMD ["-c","/start.sh"] 也可以是 CMD echo 'hello docker' |
EXPOSE | 声明容器运行的服务端口。例如:EXPOSE 80 443,但是默认都是 tcp 协议,如果想要暴漏 udp 协议,则是 EXPOSE 80/udp ,注意只能是 tcp 或 udp |
ENV | 设置容器内的环境变量。例如:ENV MYSQL_ROOT_PASSWORD 123456 |
ADD | 将宿主机目录下的文件拷贝进镜像且 ADD 命令会自动处理 URL 和解压 tar 包 例如:ADD ["src","dest"] 或者 ADD https://xxx.com/html.tar.gz (opens new window) /var/www/html 或者:ADD html.tar.gz/var/www/html |
COPY | 拷贝文件或目录到镜像(不能自动解压缩)。例如:COPY ./start.sh/start.sh |
ENTRYPOINT | 运行容器时执行的 Shell 命令(不能被运行时传递的参数覆盖),比 CMD 牛皮一些。例如:ENTRYPOINT ["/bin/bash","-c","/start.sh"] 或者 ENTRYPOINT /bin/bash -c "/start.sh" |
VOLUME | 指定容器挂载点到宿主机自动生成的目录或其他容器 例如:VOLUME ["/var/lib/mysql"] |
USER | 为 RUN,CMD 和 ENTRYPOINT 执行命令指定运行用户 例如:USER Mr_chen |
WORKDIR | 指定在创建容器后,终端默认登录进来的工作目录,一个落脚点 例如:WORKDIR /data, 该命令也会影响 ENTRYPOINT 运行例如jar包时的位置,默认会自带WORKDIR的路径 |
HEALTHCHECK | 健康检查。例如:HEALTHCHECK --interval=5m --timeout=3s --retries=3 CMD curl -f http://localhost/ (opens new window) exit 1 |
ARG | 在构建镜像时指定一些参数。例如:ARG user |
ONBUILD | 当镜像被继承后触发在 ONBUILD 里写的命令,继承者直接使用 FROM 命令继承当前镜像的名称即可,在 build 的时候触发 |
提示
从 docker17.05 版本开始,dockerfile 中允许使用多个 FROM 指令
# 配置 Idea 连接 Docker
配置后方便我们把写好的 Docker File 直接打成镜像到 Docker 中,方便运行和管理
vim /usr/lib/systemd/system/docker.service
systemctl daemon-reload // 1,加载docker守护线程
systemctl restart docker // 2,重启docker
2
# 实战构建 SpringBoot 应用
在应用的根目录中创建 Dockerfile,具体构建之前一定要了解 SpringBoot 配置文件的加载路径优先级,这里牵扯到我们在修改配置文件时,可以指定挂载外部文件修改后同步到容器,否则,每改一次都要重新制作镜像
提示
SpringBoot 配置文件的加载路径优先级:
工程根目录:./config/
工程根目录:./
classpath:/config/
classpath:/
# 基础镜像
FROM openjdk:8-jre-slim
# 作者
MAINTAINER biguncle
# 配置
ENV PARAMS=""
EXPOSE 8081
# 时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 添加应用
ADD ./target/tool-boot-0.0.1-SNAPSHOT.jar /server/tool-boot.jar
# 创建一个工作目录,并将外部配置文件复制到镜像中
RUN mkdir /server/config
COPY /src/main/resources/application.yml /app/config/
WORKDIR /server
## 在镜像运行为容器后执行的命令
ENTRYPOINT java -jar -Dpolyglot.engine.WarnInterpreterOnly=false tool-boot.jar $PARAMS
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
执行命令
#build 构建应用的镜像
docker build -f ./Dockerfile -t 875730567/easy-manager-tool .
2
运行容器
#build 构建应用的镜像
docker run -p 8081:8081 --name -v /opt:/server/config easy-manager-tool -d 875730567/easy-manager-tool
2
# 5. Docker 使用阿里云仓库或自建仓库
# 阿里云仓库
- 先登录阿里云镜像服务,地址 (opens new window)
- 创建个人或企业实例
- 创建镜像仓库,这个仓库可以建多个,看自己
- 创建完毕之后可以根据阿里云提供的步骤进行推送或拉取
如果我们只是想用阿里云的镜像加速器,可以找到如下图操作即可。
# 自建仓库
- 拉取仓库镜像
docker pull registry
- 运行镜像
docker run -d -v /edc/images/registry:/var/lib/registry
-p 5000:5000
--restart=always
--name xdp-registry registry
2
3
4
- 查看镜像信息
curl http://127.0.0.1:5000/v2/_catalog
# 6. 上传 DockerHub
- 首先保证你登录
docker login --username=xxxx
- 构建镜像
docker build -t 账号/应用名称 -f Dockerfile .
- 在 DockerHub 新建仓库 https://hub.docker.com/
- 给镜像打一个 tag 标签
docker tag 账号/应用名称 账号/标签名称:标签版本
- 上传
docker push 账号/标签名称:标签版本