各位肯定都用过Docker,平常用它来装一些中间件那不要太方便,这篇文章主要就是将Docker的知识做一个归纳总结。
学习之前,默认各位已经安装了docker还有docker-compose了。
Docker的基本命令
镜像
查看镜像
docker images
可选项
-a 列出所有镜像
-q 只显示镜像的id
搜索镜像
docker search 名称
可选项
--filter=STARS=3000 搜索出来的镜像的STARS大于3000
下载镜像
docker pull 名称[:tag]
不加:tag 默认下载最新
删除镜像
docker rmi 镜像ID
docker rmi 镜像ID 镜像ID 镜像ID #删除多个镜像
docker rmi $(docker images -aq) #删除全部镜像
容器
需要先拥有镜像才能创建容器
新建容器并启动
docker run [可选参数] image
--name="name" #容器名字
-d #后台运行
-it #交互方式运行,进入容器内部
-p 主机端口:容器端口
列出运行的容器
docker ps
-a #当前运行的容器+历史运行的容器
进入运行中的容器
docker exec -it 容器id /bin/bash
退出容器
exit #退出容器并停止
Ctrl + P + Q #容器不停止退出
删除容器
docker rm 容器id #这样不能删除运行中的容器
docker rm -f 容器id #强制删除
启动和停止容器
docker start 容器id #启动
docker restart 容器id #重启
docker stop 容器id #停止
docker kill 容器id #强制停止
从容器内拷贝文件
docker cp 容器id:容器内路径 目的主机路径
其他
查看日志
docker logs -tf -tail 10 容器id
-tf #显示日志
-tail number #显示number条日志
查看容器中进程信息
docker top 容器id
查看容器元数据
docker inspect 容器id
容器数据卷
上面是docker的一些常用命令,我们在使用docker运行镜像,很多时候需要修改文件,假如每次都需要进入容器内部,那太麻烦了,而且将容器删除,这些修改后的数据就会丢失,因此docker为我们提供了数据卷挂载的方式。
使用数据卷
# 指定路径挂载 -v 可以挂载多个
docker run -it -v 主机路径:容器内路径 -v 主机目录:容器内目录 -p 主机端口:容器端口 ...
#匿名挂载和具名挂载
docker run -v 容器内路径 ... # 匿名
docker run -v 卷名:容器内路径 ... #具名
注意:卷名和主机路径的区分就是 主机路径前都有/
所有的docker容器内的卷,没有指定主机挂载目录的情况下都是在 /var/lib/var/lib/docker/volumes/***/_data下
容器之间共享
通过关键字 --volumes-from
例如:docker run --name docker02 --volumes-from docker01 image
这样docker02和docker01就是共享数据卷了
当然出来上面的挂载方式还可以使用Dockerfile文件来进行挂载,下面进行介绍。
Dockerfile
Dockerfile就是用来构建docker镜像的构建文件,镜像是一层一层的,脚本一个个的命令都是一层。
构建步骤
- 编写一个dockerfile文件
- docker build构建成为一个镜像
- docker run 运行镜像
- docker push 发布镜像(DockerHub,阿里云镜像仓库)
指令
FROM #基础镜像,从这里开始构建
MAINTAINER #镜像谁写的,姓名+邮箱
RUN #镜像构建的时候需要运行的命令
ADD #添加内容
WORKDIR #镜像的工作目录
VOLUME #挂载的目录
EXPOSE #暴露端口
CMD #指定容器启动时要运行的命令,只有最后一个生效,可被替代
ENTRYPOINT #指定容器启动时要运行的命令,可以追加命令
ONBUILD #当构建一个被继承的Dockerfile就会运行ONBUILD指令
COPY #类似ADD,将文件拷贝到镜像中
ENV #构建时设置环境变量
例如下面这个Dockerfile
#镜像将基于 OpenJDK 8 的精简版 JRE
FROM openjdk:8-jre-slim
MAINTAINER xxx<xxx@qq.com>
#设置环境变量
ENV PARAMS=""
ENV TZ=PRC
#这个命令主要是来指定时区
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
#将构建目录下的target/xxx.jar 添加到镜像当中,并放置在根目录下,命名为xxx.jar
ADD target/xxx.jar /xxx.jar
#在启动容器会自动执行这条命令
ENTRYPOINT ["sh","-c","java -jar $JAVA_OPTS /chatgpt-api.jar $PARAMS"]
有了这个文件,我们就可以通过下面的命令来构建镜像
docker build -f Dockerfile位置 -t 镜像名称 .
Docker Compose
我们平常的项目可能需要用到很多第三方软件,或者我们本身就有很多服务,我们构建完镜像后,需要自己一个一个去启动,而且这样也体现不出项目的一个整体性。
所有为了统一管理我们的项目中的镜像,并且让他们之间有关联,我们可以使用Docker Compose,我们只需要自定义docker-compose.yml文件,在通过对应的命令来镜像容器创建和启动。
#这里就介绍几个docker-compose的常用命令
#docker-compose -f 指定docker-compose.yml路径
#docker-compose up 启动并运行服务
参数:
-d 或 --detach:以后台模式运行容器。
--build:在启动服务前构建镜像。
--force-recreate:强制重新创建容器,即使容器已经存在。
--no-deps:不启动依赖的服务。
--scale SERVICE=NUM:设置服务的副本数量。
#如下
docker-compose -f docker-compose.yml up -d
docker-compose.yml文件编写
docker-compose.yml文件其实就是将一个个容器启动命令集合在一起,所以它的编写可以和启动容器的那些参数基本上一一对应,当然有一些可能会有一些区别,具体可以去网上查询
如下,这是一个nginx编写方式,注意,这些挂载的目录或文件需要先创建好
nginx:
image: nginx:1.25.3
container_name: nginx
restart: always
ports:
- '443:443'
- '80:80'
volumes:
- ./nginx/logs:/var/log/nginx
- ./nginx/html:/usr/share/nginx/html
- ./nginx/conf/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/conf/conf.d:/etc/nginx/conf.d
privileged: true
#对应
docker run
--name nginx
--restart always
-p 443:443
-p 80:80
-v ./nginx/logs:/var/log/nginx
-v ./nginx/html:/usr/share/nginx/html
-v ./nginx/conf/nginx.conf:/etc/nginx/nginx.conf
-v ./nginx/conf/conf.d:/etc/nginx/conf.d
nginx:1.25.3
其中:
nginx 对应一个nginx服务,在 Docker Compose 的术语中,一个“服务”是指一组运行相同镜像的容器实例
image 指定镜像
container_name 指定容器名
ports 指定端口绑定关系
volumes 数据卷挂载
privileged 这个参数是给启动容器时赋予它更多的权限,使其接近宿主机的权限级别
当然,上述这是举一个例子,还有很多其他的命令:
指定网络
指定网络后在同一个网络下的容器可以互相通过服务名来进行连接
创建网络
networks: 自定义网络名: driver: bridge
需要将服务添加进某个网络加上下面这个命令
networks: - 网络名
设置参数
environment: - xxx=xxx
依赖关系
指定一个服务必须等待其他服务启动之后才能启动
depends_on:
- db
- cache
在这个例子中,该服务依赖于 db 和 cache 服务。这意味着 Docker Compose 在启动该服务之前,会先启动并等待 db 和 cache 服务完成启动。
注意:
顺序保证:depends_on 只能保证服务启动的顺序,但不能保证服务已经完全准备就绪。例如,数据库服务可能已经启动,但还没有完成初始化或建立好所有索引。为了确保服务真正可用,你可能还需要使用健康检查(health checks)或其他机制。
条件等待:从 Docker Compose v3.4 开始,你还可以使用 condition 参数来更精确地控制依赖条件。例如,你可以等待直到服务通过健康检查:如:
depends_on: redis: condition: service_healthy mysql: condition: service_healthymysql和redis需要定义健康检查
healthcheck: test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ] interval: 5s timeout: 10s retries: 10 start_period: 15shealthcheck: test: [ "CMD", "redis-cli", "ping" ] interval: 10s timeout: 5s retries: 3
Docker Desktop
这是Docker官方提供的可以在windows和mac上运行的Docker服务,可以去官网进行下载,注意下载之前查看电脑上是否有hyper-v 和 wsl ,剩下的一顿点点点就可以了,安装完成后最好将镜像路径换一下。
在自己电脑上安装docker后,就不需要在将代码和dockerfile传到linux服务器进行镜像构建,可以本地构建完成后,在上传到DockerHub上面,后续可以直接在linux进行镜像的拉取,DockerHub的注册和登录很简单,这里就不介绍了。
其实还通过idea连接linux上面的docker也可以,这需要在linux上对docker进行设置,使他可以提供远程服务,但是这样好像不能指定镜像的名称和版本,也不好进行镜像的管理,所以不推荐。
结尾
这篇文章对Docker的知识进行了介绍,虽然不太深入,但是可以应对日常使用了。后续可以去购买书籍或者看教学视频进行更加深入的学习。