Docker 镜像 是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)
Docker支持将软件编译成一个镜像,然后在镜像中各种软件做好配置,将镜像发布出去,其他使用者可以直接使用这个镜像。运行中的这个镜像称为容器,容器启动是非常快速的。
即打包好的软件,所有环境都配置好了,开箱即用,无需再配置
文章参考:
相关资源:
从 Docker 镜像仓库获取镜像的命令是 docker pull
。其命令格式为:
<域名/IP>[:端口号]
。默认地址是 Docker Hub(docker.io
)<用户名>/<软件名>
。对于 Docker Hub,如果不给出用户名,则默认为 library
,也就是官方镜像# 官方镜像
docker image pull 镜像名称
# 或简写为
docker pull 镜像名称
# 比如
docker pull ubuntu
docker pull ubuntu:18.04
# 个人镜像
docker pull 仓库名称/镜像名称
docker pull xunmi/django
# 第三方仓库拉去
docker pull 第三方仓库地址/仓库名称/镜像名称
docker pull hub.c.163.com/library/mysql:latest
(默认仓库名为library,所有从官方获取镜像相当于`sudo docker image pull library/镜像名称`)
docker image ls
# 或者
docker images
docker image ls ubuntu:18.04
docker image rm 镜像名/镜像ID
# 或简写为
docker rmi 镜像名/镜像ID
docker image rm hello-world
docker rmi 9e64176cd8a2
镜像只是一个只读类型的文件,我们需要把这个镜像加载成我们的环境,也就是让他变成容器。
docker run [可选参数] 镜像名 [向启动容器中传入的命令]
常用可选参数 | 作用 |
---|---|
-i | 表示以交互式操作运行容器。 |
-d | 会创建一个守护式容器在后台运行(这样创建容器后不会自动登录容器)。 |
-t | 表示容器启动后会进入其命令行。 -it表示容器需要交互式终端 ,即分配一个伪终端。 |
–name | 为创建的容器命名。(默认会随机给名字,不支持中文字符!!!) |
-v | 目录映射,即宿主机目录:容器中目录。注意:最好做目录映射,在宿主机上做修改,然后共享到容器上。 |
-p | 端口映射,即宿主机端口:容器中端口。 比如:-p 8080:80 就是将容器中的80端口,映射到主机中的8080端口 |
-network=host | 表示将主机的网络环境映射到容器中,使用此命令会让容器和主机共享一个网络空间。 |
bash
docker run -it ubuntu:18.04 bash
# 启动docker lab容器,输入localhost:8080即可使用
docker run -d -p 8080:80 docker/getting-started
# Docker 以 ubuntu15.10 镜像创建一个新容器,然后在容器里执行 bin/echo "Hello world",然后输出结果
runoob@runoob:~$ docker run ubuntu:15.10 /bin/echo "Hello world"
Hello world
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZMbgvnN4-1674114793665)(C:\Users\sommer.liu\Desktop\学习笔记\后端开发技术栈\docker.assets\image-20230119150147176.png)]
# 查看当前所有正在运行的容器
docker ps
# 查看当前所有的容器
docker ps -a
# 使用过滤器(除了name外,常用的还可以指定id:id= 、所有停止的容器:status=exited,正在运行的容器:status=running 等)
docker ps -f name=指定的名字
# 显示2个上次创建的容器(2可以改变)
docker ps -n 2
# 显示最新创建的容器(包括所有状态)
docker ps -l
# 仅显示ip
docker ps -q
# 显示容器大小
docker ps -s
stop和kill的区别: stop类似正常退出一个软件,而kill是当一个进程出现意外无法正常关闭的时候,强行关闭,有点像使用任务管理器进行结束进程操作
# 停止容器
docker container stop 容器名/容器id
# 或可简写为
docker stop 容器名/容器id
# 强制关闭容器
docker container kill 容器名/容器id
# 或可简写为
docker kill 容器名/容器id
# 启动容器
docker container start 容器名/容器id
# 或可简写为
docker start 容器名/容器id
如果报错Error response from daemon: You cannot remove a running container 容器ID. Stop the container before attempting removal or force remove
则代表这个容器已经启动,需要执行 docker stop 容器id,停止此容器
# 使用rm删除容器
docker rm 容器名/容器id
# 列如
docker rm docker-test
# 将容器制作成镜像
docker commit 容器名 镜像名
# 镜像打包备份(打包备份的文件会自动存放在当前命令行的路径下,如果想让保存的文件可以打开,可以加.tar后缀)
docker save -o 保存的文件名 镜像名
# 镜像解压
docker load -i 文件路径/备份文件
目前 Docker 官方维护了一个公共仓库 Docker Hub。大部分需求都可以通过在 Docker Hub 中直接下载镜像来实现。
在 https://hub.docker.com 免费注册一个 Docker 账号。登录需要输入用户名和密码,登录成功后,我们就可以从 docker hub 上拉取自己账号下的全部镜像。
$ docker login
退出 docker hub 可以使用以下命令:
$ docker logout
用户登录后,可以通过 docker push 命令将自己的镜像推送到 Docker Hub。
docker tag ubuntu:18.04 username/ubuntu:18.04
docker push username/ubuntu:18.04
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像。这个脚本就是 Dockerfile。
注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。以 && 符号连接命令,执行后只会创建 1 层镜像。
在 Dockerfile
文件所在目录执行构建动作。便可通过目录下的 Dockerfile 构建一个 nginx:v3(镜像名称:镜像标签)。
docker build [选项] <上下文路径/URL/->
docker build -t dtf_service:v1 . #这个.是在指定上下文目录,docker build 命令会将该目录下的内容打包交给 Docker 引擎以帮助构建镜像
docker build -t nginx:v3 . # 指定了最终镜像的名称 -t nginx:v3
# docker build 还支持从 URL 构建,比如可以直接从 Git repo 中构建
docker build -t hello-world https://github.com/docker-library/hello-world.git #master:amd64/hello-world
上下文路径,是指 docker 在构建镜像,有时候想要使用到本机的文件(比如复制),docker build 命令得知这个路径后,会将路径下的所有内容打包。
解析:由于 docker 的运行模式是 C/S。我们本机是 C,docker 引擎是 S。实际的构建过程是在 docker 引擎下完成的,所以这个时候无法用到我们本机的文件。这就需要把我们本机的指定目录下的文件一起打包提供给 docker 引擎使用。
如果未说明最后一个参数,那么默认上下文路径就是 Dockerfile 所在的位置。
注意:上下文路径下不要放无用的文件,因为会一起打包发送给 docker 引擎,如果文件过多会造成过程缓慢。
from ubuntu:latest #指定基础镜像
run apt update \ # shell格式的命令,就像直接在命令行中输入的命令一样
&& apt install sudo \
&& apt install net-tools \
&& apt install jq -y \
&& mkdir /home/djitool
copy . /home/djitool/ # 从上下文目录中复制文件或者目录到容器里指定路径
run cd /home/djitool/ \
&& sudo ./upgrade.sh
expose 5100 5101 #声明容器运行时提供服务的端口,仅仅是声明容器打算使用什么端口而已,并不会自动在宿主进行端口映射。
entrypoint ["/home/dji/dtf/start.sh","5101"]
dockerfile 的命令摘要
FROM- 镜像从那里来
MAINTAINER- 镜像维护者信息
RUN- 构建镜像执行的命令,每一次RUN都会构建一层
CMD- 容器启动的命令,如果有多个则以最后一个为准,也可以为ENTRYPOINT提供参数
VOLUME- 定义数据卷,如果没有定义则使用默认
USER- 指定后续执行的用户组和用户
WORKDIR- 切换当前执行的工作目录
HEALTHCHECH- 健康检测指令
ARG- 变量属性值,但不在容器内部起作用
EXPOSE- 暴露端口
ENV- 变量属性值,容器内部也会起作用
ADD- 添加文件,如果是压缩文件也解压
COPY- 添加文件,以复制的形式
ENTRYPOINT- 容器进入时执行的命令
开机自启动:ENTRYPOINT和CMD都是让用户指定一个可执行程序, 这个可执行程序在container启动后自动启动.
CMD
作用是指定具体的参数
shell
格式的话,实际的命令会被包装为 sh -c
的参数的形式进行执行,docker用/bin/sh -c的语法调用.CMD ["executable","param1","param2"] (exec form, this is the preferred form)
CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
CMD command param1 param2 (shell form)
# 例如
FROM ubuntu:trusty
CMD ping localhost # 相当于实际运行的命令是 /bin/sh -c 'ping localhost'.
CMD ["/bin/ping","localhost"]
# 例如
CMD ["/bin/echo", "this is a echo test"]
# 运行镜像
docker run test # docker run命令如果指定了参数会把CMD里的参数覆盖,如docker run -it ubuntu /bin/bash
# 输出
this is a echo test
ENTRYPOINT入口点
用于设定容器启动时第一个运行的命令及其参数,任何使用docker run
命令传入的参数都会附加在entrypoint
指令之后
FROM ubuntu:trusty
ENTRYPOINT ["/bin/ping","-c","3"]
CMD ["localhost"]
# 相当于 /bin/ping -c 3 localhost,用shell命令行发送ping请求3次
ENTRYPOINT [ "sh", "-c", "echo $HOME" ] # 相当于 sh -c echo $HOME,即用shell命令行 执行echo $HOME命令
另外一种形式是使用一个脚本作为ENTRYPOINT
的值。按照惯例来说,脚本名中通常包含entrypoint
关键字。在这个脚本中,你可以做相关的配置,设置环境变量等,例如下面代码:
COPY ./docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["postgres"]
例如,下面就是Postgres官方镜像中的ENTRYPOINT
脚本中的内容:
#!/bin/bash
set -e
if [ "$1" = 'postgres' ]; then
chown -R postgres "$PGDATA"
if [ -z "$(ls -A "$PGDATA")" ]; then
gosu postgres initdb
fi
exec gosu postgres "$@"
fi
exec "$@"
将本机内容复制到docker 容器中 docker cp 源地址 容器名称:目标地址
docker cp D:\cts\cts-0825 59082bc9f284fe4b1309e3bd617b65c5506c6446f8098b317114f9e11b0a3f9b:/app/
查看已有端口 docker image
docker run -it -p 8080:8080 yushl/tomcat /bin/bash # 指定本机端口映射容器端口
docker run -it -p 127.0.0.1:5100:5100 -p 127.0.0.1:5102:5102 ubuntu # 指定本机ip:端口映射
查看正在运行的容器:docker ps
查看容器的端口映射信息:docker port 容器名称
每次启动新的ubuntu容器,原先下载的东西都会没有
# 增加新的用户
adduser sommer
# 修改用户的sudo 权限
vim /etc/sudoers
# 在/etc/sudoers文件中找到root ALL=(ALL:ALL) ALL,在该行下面添加:
sommer ALL=(ALL:ALL) ALL
# 包括但不限于以下update方法
sudo apt-get update
sudo apt-get upgrade
sudo apt update
# 下载安装 vim sudo
apt-get update
apt-get install vim
apt-get install sudo