一 Docker概述
一 Docker是什么
二 Docker和虚拟机技术的不同
- 传统虚拟机,虚拟出一条硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件
- 容器内的应用直接运行在宿主机的内容,容器是没有自己的内核的,也没有虚拟我们的硬件,所以就轻便了
- 每个容器间是互相隔离,每个容器内都有一个属于自己的文件系统,互不影响
三 Docker的优点
二 Docker安装
一 Docker的基本组成
二 安装Docker
1 环境准备(Linux要求内核3.0以上 )
~ uname -r 4.15.0-96-generic # 要求3.0以上
2 安装
#1.卸载旧版本 yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine #2.需要的安装包 yum install -y yum-utils #3.设置镜像的仓库 yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo#默认是从国外的,不推荐 #推荐使用国内的 yum-config-manager \ --add-repo \ https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo #4. 更新yum软件包索引 yum makecache fast #5.安装docker相关的 docker-ce 社区版 而ee是企业版 yum install docker-ce docker-ce-cli containerd.io #6. 使用docker version查看是否按照成功 docker version
#7. 测试 ➜ ~ docker run hello-world Hello from Docker! This message shows that your installation appears to be working correctly. ... #8.查看一下下载的镜像 ➜ ~ docker images REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest bf756fblae65 4months ago 13.3kB
了解:卸载docker
#1. 卸载依赖 yum remove docker-ce docker-ce-cli containerd.io #2. 删除资源 rm -rf /var/lib/docker # /var/lib/docker 是docker的默认工作路径!
3 配置镜像加速器
三 Docker的常用命令
1 帮助命令
docker version #显示docker的版本信息。 docker info #显示docker的系统信息,包括镜像和容器的数量 docker 命令 --help #帮助命令
2 镜像命令
docker images #查看所有本地主机上的镜像 可以使用docker image ls代替 docker search 搜索镜像 docker pull 下载镜像 docker image pull docker rmi 删除镜像 docker image rm
3 容器命令
3.1 新建容器并启动
docker run 镜像id --name="Name" # 容器名字 tomcat01 tomcat02 用来区分容器 -d # 后台方式运行 -it # 使用交互方式运行,进入容器查看内容 -p # 指定容器的端口 -p 8080(宿主机):8080(容器) -p ip:主机端口:容器端口 -p 主机端口:容器端口(常用) -p 容器端口 -P(大写) 随机指定端口
3.2 列出所有运行的容器
docker ps # 默认列出正在运行的容器 -a, --all # 显示所有容器 -n, --last int # 显示最后一个创建的容器 -q, --quiet # 仅显示容器ID
3.3 启动和停止容器的操作
docker start 容器id #启动容器 docker restart 容器id #重启容器 docker stop 容器id #停止当前正在运行的容器 docker kill 容器id #强制停止当前容器
3.4 删除容器
docker rm 容器id #删除指定的容器,不能删除正在运行的容器,如果要强制删除 rm -rf docker rm -f $(docker ps -aq) #删除指定的容器 docker ps -a -q|xargs docker rm #删除所有的容器
3.5 退出容器
exit #容器直接退出 ctrl +P +Q #容器不停止退出
3.6 查看日志
docker logs -tf # 显示日志信息(一直更新) --tail number #需要显示日志条数 docker logs -t --tail n 容器ID # 查看n行日志 docker logs -ft 容器ID # 跟着日志 --details #Show extra details provided to logs -f, --follow # Follow log output --since string # Show logs since timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes) --tail string # Number of lines to show from the end of the logs(default "all") -t, --timestamps # Show timestamp --until string # Show logs before a timestamp
3.7 查看容器中进程信息
docker top 容器ID
3.8 查看容器详细信息【包括创建者,各层 layer
的数字摘要等】
docker inspect 容器ID
3.9 进入正在运行的容器
docker exec -it 容器ID /bin/bash
3.10 容器与宿主机间传输文件
docker cp 容器ID:容器内路径/default.conf 宿主机路径
docker cp 宿主机文件 容器ID:容器内路径/index.html
3.11 commit镜像:保存当前的容器状态获得一个镜像
docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[TAG]
3.12 使用save和load
# 将镜像保存为tar包:
docker save -o <tar包名>.tar <镜像名>:<tag>
# 以同时将多个 image 打包成一个文件
docker save -o images.tar postgres:9.6 mongo:3.4
# 从tar包导入镜像
docker load -i <tar包名>.tar ---- 从 tar 包导入镜像
3.13 使用export和import
# 根据容器 ID 将镜像导出成一个文件。
docker export f299f501774c > hangger_server.tar
# 将这个镜像文件导入进来。
docker import - new_hangger_server < hangger_server.tar
⚠️ 特别注意:两种方法不可混用。
如果使用 import 导入 save 产生的文件,虽然导入不提示错误,但是启动容器时会提示失败,会出现类似"docker: Error response from daemon: Container command not found or does not exist"的错误。
1 文件大小不同 # export 导出的镜像文件体积小于 save 保存的镜像 2 是否可以对镜像重命名 # docker import 可以为镜像指定新名称 # docker load 不能对载入的镜像重命名 3 是否可以同时将多个镜像打包到一个文件中 # docker export 不支持 # docker save 支持 4 是否包含镜像历史 # export 导出(import 导入)是根据容器拿到的镜像,再导入时会丢失镜像所有的历史记录和元数据信息(即仅保存容器当时的快照状态),所以无法进行回滚操作。 # 而 save 保存(load 加载)的镜像,没有丢失镜像的历史,可以回滚到之前的层(layer)。 5 应用场景不同 # docker export 的应用场景:主要用来制作基础镜像,比如我们从一个 ubuntu 镜像启动一个容器,然后安装一些软件和进行一些设置后,使用 docker export 保存为一个基础镜像。然后,把这个镜像分发给其他人使用,比如作为基础的开发环境。 # docker save 的应用场景:如果我们的应用是使用 docker-compose.yml 编排的多个镜像组合,但我们要部署的客户服务器并不能连外网。这时就可以使用 docker save 将用到的镜像打个包,然后拷贝到客户服务器上使用 docker load 载入。
3.14 docker容器指定自定义IP
# 查看 dockers 的网络类型 docker network list (1)bridge 桥接网络 默认网络类型,容器内不特殊指定,就用此类型。不特殊指定的话,分配的 ip 为 172.17.0.x (2)none 无指定网络 容器内不指定局域网 ip host (3)主机网络和主机共用一个 ip,会出现和宿主机争抢端口情况,非特殊需要尽量少用
docker 容器自定义 ip 理解
根据 docker 网络模式,
bridge 可以自定义网桥进行固定 ip
none 无指定网络肯定不行
host 使用主机网络会跟宿主机挣抢端口,所以并不常用
最常用的就是利用 bridge, 自定义虚拟网桥来固定 ip 默认情况下,docker 的容器重启之后,会自动分配 ip,导致一次重启 ip 变化。所以需要对 docker 容器指定 ip 由于 docker 默认的网络不能固定 ip 地址,我们创建自定义虚拟网桥,进行固定 ip 的分配
docker 自定义 ip 操作
# 创建自定义网桥 docker network create --subnet=x.x.x.0/24 netBridgeName (网桥名称,随便写即可) # 创建容器且指定网络 ip docker run -itd --network=netBridgeName --ip x.x.x.8 --name containerName imageName # 查看 docker 下网络模式 docker network list # 删除创建的网桥 docker network rm netBridgeName
⚠️ 值得注意的是:网络段不要和主机网络段冲突,要不然会影响宿主机
四 容器数据卷
将docker容器中产生的数据,同步到本地。通过目录的挂载,将容器内的目录,挂载到Linux上面。实现容器的持久化和同步操作,实现容器间的数据共享。
一 使用数据卷
docker run -it --name 容器名 -p 主机端口:容器内端口 -v 主机目录:容器内目录 centos /bin/bash # 通过 docker inspect 容器ID 查看
测试:
docker run -it -v /home/ceshi:/home centos /bin/bash # docker inspect 32b88c0f8db3 # 查看数据卷挂载
我们以后只需要在本地修改即可,容器内会自动同步
二 具名和匿名挂载
1 匿名挂载
docker run -d -P --name nginx01 -v /etc/nginx nginx # 查看所有的volume的情况 docker volume ls DRIVER VOLUME NAME local 33ae588fae6d34f511a769948f0d3d123c9d45c442ac7728cb85599c2657e50d local # 这里发现,这种就是匿名挂载,我们在 -v只写了容器内的路径,没有写容器外的路劲!
2 具名挂载
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx docker volume ls DRIVER VOLUME NAME local juming-nginx # 通过 -v 卷名:容器内路径 # 查看一下这个卷
# 所有的docker容器内的卷,没有指定目录的情况下都是在/var/lib/docker/volumes/xxxx/_data 下。如果指定了目录,docker volume ls 是查看不到的。
3 扩展
# 通过 -v 容器内路径: ro rw 改变读写权限 ro #readonly 只读 rw #readwrite 可读可写 docker run -d -P --name nginx05 -v juming:/etc/nginx:ro nginx docker run -d -P --name nginx05 -v juming:/etc/nginx:rw nginx # ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作!
五 Dockerfile
一 介绍
dockerfile是用来构建docker镜像的文件。命令参数脚本
构建步骤:
- 编写一个dockerfile文件
- docker build -f 文件路径 -t 镜像名:[tag] . 构建镜像
- docker run 运行镜像
- docker push 发布镜像
二 构建过程
Dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单! Docker镜像逐渐成企业交付的标准,必须要掌握!
Dockerfile常用指令
FROM # 基础镜像,一切从这里开始构建 MAINTAINER # 镜像是谁写的, 姓名+邮箱 RUN # 镜像构建的时候需要运行的命令 ADD # 步骤,tomcat镜像,这个tomcat压缩包!添加内容 添加同目录 WORKDIR # 镜像的工作目录 VOLUME # 挂载的目录 EXPOSE # 保留端口配置 CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代。 ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令 ONBUILD # 当构建一个被继承 DockerFile 这个时候就会运行ONBUILD的指令,触发指 令。 COPY # 类似ADD,将我们文件拷贝到镜像中 ENV # 构建的时候设置环境变量!
CMD和ENTRYPOINT的区别
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替 代。 ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令

# 编写dockerfile文件 $ vim dockerfile-test-cmd FROM centos CMD ["ls","-a"] # 构建镜像 $ docker build -f dockerfile-test-cmd -t cmd-test:0.1 . # 运行镜像 # 想追加一个命令 -l 成为ls -al $ docker run cmd-test:0.1 -l # 报错 $ vim dockerfile-test-entrypoint FROM centos ENTRYPOINT ["ls","-a"] $ docker run entrypoint-test:0.1 -l total 56 ...
三 实战:Tomcat镜像
1 准备镜像文件
准备tomcat 和 jdk到当前目录,编写好README 。
2 编写dockerfile
FROM centos MAINTAINER xx COPY README /usr/local/README #复制文件 ADD jdk-8u231-linux-x64.tar.gz /usr/local/ #复制解压 ADD apache-tomcat-9.0.35.tar.gz /usr/local/ #复制解压 RUN yum -y install vim ENV MYPATH /usr/local #设置环境变量 WORKDIR $MYPATH #设置工作目录 ENV JAVA_HOME /usr/local/jdk1.8.0_231 #设置环境变量 ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.35 #设置环境变量 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib #设置环境变量 分隔符是: EXPOSE 8080 #设置暴露的端口 CMD /usr/local/apache-tomcat-9.0.35/bin/startup.sh && tail -F /usr/local/apache- tomcat-9.0.35/logs/catalina.out # 设置默认命令
3 构建镜像
# 因为dockerfile命名使用默认命名 因此不用使用-f 指定文件
docker build -t mytomcat:0.1 .
4 run镜像
docker run -d -p 8080:8080 --name tomcat01 -v /home/kuangshen/build/tomcat/test:/usr/local/apache-tomcat-9.0.35/webapps/test - v /home/kuangshen/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.35/logs mytomcat:0.1
5 访问测试
6 发布项目(由于做了卷挂载,我们直接在本地编写项目就可以发布了!)
四 发布自己的镜像
- 地址 https://hub.docker.com/
- 确定这个账号可以登录
- 登录
- 提交push镜像
!# 会发现push不上去,因为如果没有前缀的话默认是push到 官方的library # 解决方法 # 第一种 build的时候添加你的dockerhub用户名,然后在push就可以放到自己的仓库了 $ docker build -t chengcoder/mytomcat:0.1 . # 第二种 使用docker tag #然后再次push $ docker tag 容器id chengcoder/mytomcat:1.0 #然后再次push
六 Docker网络
一 理解docker0
# 运行一个tomcat03 --link tomcat02 $ docker run -d -P --name tomcat03 --link tomcat02 tomcat 5f9331566980a9e92bc54681caaac14e9fc993f14ad13d98534026c08c0a9aef # 用tomcat03 ping tomcat02 可以ping通 $ docker exec -it tomcat03 ping tomcat02 PING tomcat02 (172.17.0.3) 56(84) bytes of data. 64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.115 ms # 用tomcat02 ping tomcat03 ping不通
二 自定义网络
1 查看所有的docker网络
网络模式:
bridge :桥接 docker(默认,自己创建也是用bridge模式)
none :不配置网络,一般不用
host :和所主机共享网络
container :容器网络连通(用得少!局限很大)
2 自定义网络
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
启动两个tomcat,再次查看网络情况
在自定义的网络下,服务可以互相ping通,不用使用–link
好处:
redis -不同的集群使用不同的网络,保证集群是安全和健康的
mysql-不同的集群使用不同的网络,保证集群是安全和健康的
3 网络连通
要将tomcat01 连通 tomcat—net-01 ,连通就是将 tomcat01加到 mynet网络 一个容器两个ip(tomcat01)
结论:假设要跨网络操作别人,就需要使用docker network connect 连通!
三 实战(部署Redis集群)
docker搭建redis集群完成!

# 创建网卡 docker network create redis --subnet 172.38.0.0/16 # 通过脚本创建六个redis配置 for port in $(seq 1 6);\ do \ mkdir -p /mydata/redis/node-${port}/conf touch /mydata/redis/node-${port}/conf/redis.conf cat << EOF >> /mydata/redis/node-${port}/conf/redis.conf port 6379 bind 0.0.0.0 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 cluster-announce-ip 172.38.0.1${port} cluster-announce-port 6379 cluster-announce-bus-port 16379 appendonly yes EOF done # 通过脚本运行六个redis for port in $(seq 1 6);\ docker run -p 637${port}:6379 -p 1667${port}:16379 --name redis-${port} \ -v /mydata/redis/node-${port}/data:/data \ -v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \ -d --net redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf docker exec -it redis-1 /bin/sh #redis默认没有bash redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1
七 Docker-compose编排工具
1 安装
# wget https://github.com/docker/compose/releases/download/v2.5.0/docker-compose-linux-x86_64 # mv docker-compose-linux-x86_64 /usr/local/bin/docker-compose # chmod a+x /usr/local/bin/docker-compose
2 yml文件

version: "3.7" services: web1: image: nginx:1.23.1 restart: always ports: - "443:443" container_name: "web1" volumes: - ./fuguangweb:/home/fuguangweb - ./fuguangapi/statics:/home/fuguangapi/static - ./conf/nginx/web.conf:/etc/nginx/conf.d/nginx.conf - ./conf/nginx/cert:/etc/nginx/cert networks: - default mysql_master: image: mysql:8.0.30 restart: always container_name: mysql_master networks: - default environment: - "MYSQL_ROOT_PASSWORD=root2021" - "MYSQL_USER=fuguang" - "MYSQL_PASSWORD=fuguang" - "MYSQL_DATABASE=fuguang" - "TZ=Asia/Shanghai" command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci --explicit_defaults_for_timestamp=true ports: - 3306:3306 volumes: - ./data/mysql:/var/lib/mysql - ./logs/mysql:/var/lib/logs - ./initdb:/docker-entrypoint-initdb.d/ redis_master: image: redis:6.2.6-alpine3.15 restart: always networks: - default ports: - "6379:6379" command: "redis-server /usr/local/etc/redis/redis.conf" container_name: redis_master volumes: - ./conf/redis/master.conf:/usr/local/etc/redis/redis.conf - ./data/redis/master:/data elasticsearch1: image: elasticsearch:7.16.1 restart: always environment: - "discovery.type=single-node" - "bootstrap.memory_lock=true" - "ES_JAVA_OPTS=-Xms256m -Xmx256m" - "xpack.security.enabled=false" - "http.cors.enabled=true" - "http.cors.allow-origin=*" ulimits: memlock: soft: -1 hard: -1 volumes: - ./data/elastic:/usr/share/elasticsearch/data - ./logs/elastic:/var/log/elasticsearch - ./plugins:/usr/share/elasticsearch/plugins ports: - 9200:9200 networks: - default api1: build: . image: fuguangapi:1.0.0 container_name: api1 restart: always ports: - 8000:8000 networks: - default volumes: - ./fuguangapi:/fuguangapi command: > sh -c "uwsgi --socket :8000 --workers 4 --master --enable-threads --module fuguangapi.wsgi" environment: - "DJANGO_SETTINGS_MODULE=fuguangapi.settings.pro" depends_on: - mysql_master - redis_master - elasticsearch1 networks: default:
3 启动服务
docker-compose -f docker-compose.yml down docker-compose -f docker-compose.yml up -d # 等待1分钟后给elasticsearch构建索引 docker exec -it api1 python manage.py rebuild_index
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现