简单的来说docker就是一种虚拟化的技术,但其实软件级的虚拟化。
Docker主要解决的问题
1、环境不一致 :代码写好,中间件装不上;生产环境OS和软件不兼容 2、环境切换痛苦 :开发→测试→准生产→生产,每个环境都要重新配置 3、版本管理混乱:U盘/网盘/传输助手来回传,依赖冲突频发
Docker核心思想
一次构建,多次使用
Docker相当于手机「应用商店」:
-
Build:快速把应用打包成镜像
-
Share:把镜像发布到Docker Hub社区
-
Run:一行命令启动应用
Docker工作流:
┌──────────┐ ┌──────────────┐ ┌──────────────┐
│ Client │────▶│ Daemon │────▶│ Registry │
│ (docker) │◀────│ (dockerd) │◀────│ (Docker Hub) │
└──────────┘ └──────────────┘ └──────────────┘
│
▼
┌──────────────┐
│ Containers │
│ (运行实例) │
└──────────────┘
Docker主要是通过容器化的思想来实现:
-
类似轻量级VM
-
共享操作系统内核
-
拥有自己的文件系统、CPU、内存、进程空间
-
互相隔离
-
轻量、快速(秒级启动)、隔离、跨平台、高密度
安装Docker(以Ubuntu系统为例)
<Install Docker Engine on Ubuntu | Docker Docs>访问这个官方网址有安装手册 执行到搭建docker仓库的时候应该会报错,现在国内不允许访问docker,除非是使用梯子

我们现在更换国内的源 依次执行如下的代码:
#清理原有失效配置,不然可能会冲突报错
# 删除失效的密钥文件、源文件
sudo rm -f /etc/apt/keyrings/docker.asc
sudo rm -f /etc/apt/sources.list.d/docker.sources
#改用清华镜像导入 Docker GPG 密钥(国内稳定)
# 创建密钥目录
sudo install -m 0755 -d /etc/apt/keyrings
# 从清华镜像拉取Docker公钥
sudo curl -fsSL https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
#写入清华 Docker 软件源
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu
Suites: $(. /etc/os-release && echo "$VERSION_CODENAME")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
#更新源并安装 Docker
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
安装完成后查看docker是否运行,如果没有尝试手动启动
#查看是否启动
sudo systemctl status docker
#手动开启
sudo systemctl start docker
#设置开机自启动
sudo systemctl enable docker

配置国内加速
配置加速,docker下载东西默认是访问docker hub速度比较慢
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
docker基本命令
docker search #检索
docker pull #下载
docker images #镜像列表
docker rmi #删除镜像
docker run #启动一个容器
docker exec #进入容器内部
docker ps #查看正在运行的容器
docker start 容器ID或者容器名字 #开始一个容器
docker stats 容器ID或者容器名字 #查看一个容器的状态
docker logs ID或者名字 #看日志
docker rm ID 删除容器 #删除容器
docker rm -f ID 强制删除 #强制删除,正在运行的也删除
镜像操作
镜像就相当于是手机应用市场内的APP一样
命名为,镜像名:标签
如果需要下载指定的版本上docker hub上去搜索相应的版本
docker images ls #查看当前全部的镜像
docker rmi 镜像名 #删除镜像的两种方式
docker rmi docker的ID
docker search nginx #查看对于这个镜像的描述
docker run 细节
docker run --hlep 查看帮助
格式:
docker run 参数1 参数2 …… 镜像名
eg:docker run nginx 不加标签,就默认最新版的
这个容器会一直在终端显示,如果终端关掉,就会断掉,控制阻死行为
如果没有下载这个镜像,它会自己下载镜像最新版
eg:
docker run -d --name myapp nginx
参数解释:
-d 代表后台运行
--name 重命名为myapp
-p 端口映射,每一个程序在容器内部运行,不做映射,外部无法访问,每个容器是独立微型linux服务器
docker run -d --name app01 -p 80:80 nginx
翻译
1、后台运行一个容器
2、重命名为app01
3、-p 80:80 端口映射,前面是物理主机的端口:后面为容器的端口
4、镜像为nginx最新版
nginx的默认页面信息在那,需要上docker hub上查看,翻阅文档发现在,/usr/share/nginx/html
我们现在需要修改容器内的页面信息
执行如下的命令进入容器
docker exec -it app01 /bin/bash
翻译
1、-it 以交互的形式
2、/bin/bash 终端的形式
进入后执行 echo "hello word" >>html
这个时候使用IP进行访问就会出现内容为 hello world
保存镜像
前面我们修改了镜像,现在我们需要将镜像上传到社区
docker commit #将经由你改变的镜像上传到社区
docker save #保存到本地
docker load #其他人拿到这个镜像后进行,加载镜像
eg:
docker commit -m "update index.html" 容器 指定镜像
docker save -o mynginx.tar mynginx:v1.0 #将产生变化的镜像保存到本地
然后就会生成一个tar包,可以通过u盘进行拷贝,给别人使用
别人拿到镜像后
docker load -i mynginx.tar
-i 指定镜像包
分享社区
浏览器访问docker hub进行登录
然后进入主机上
docker login
然后输入用户,密码
docker tag #命名
docker push #推送到社区
docker tag 原本的镜像 用户名/自己命名
社会为了区分每个镜像,都是用户名加镜像名
目录挂载
容器运行的时候数据和内容都在容器内,要是容器炸了,数据就丢失了,造成数据丢失
docker ps -aq 打印所有的容器的ID
docker rm $(docker ps -aq) #拿到所有的容器的ID进行删除
启动官方的nginx的页面是官方的内容
进行配置文件的路径,然后修改相关的文档
进入容器内,连修改的vi命令都没有,只要echo执行,所有管理机器不方便
容器一销毁,文件数据全部丢失
这个时候就有目录挂载
主机的目录 /app/nghtml
容器的目录 /usr/share/nginx/html
eg:
docker run -d --name app01 -p 80:80 \
-v /app/nghtml:/usr/share/nginx/html \
nginx
-v 主机的目录:容器的目录
外部目录如果未创建,则会自己创建
现在进行访问,没有显示,因为现在的访问是外部的目录,但是外部的目录没有东西,自己可以写东西
现在在容器内修改内容,外部的目录下的内容也会改变
卷映射
卷名不以点杠,目录路径开始
我现在要求外面的配置文件和容器内的配置文件保持一直
格式:
-v ngconf:/etc/nginx
docker run -d --name myapp -p 99:80\
-v /app/nghtml:/usr/share/nginx/html\
-v ngconf:/etc/nginx \
nginx
看卷名
默认放的卷名在
/var/lib/docker/volumes/_data/卷名
我现在外部修改一个配置文件后,在容器内也会产生修改
docker volumes ls 列出所有的卷
docker volumes create 卷名 创建卷
docker volumes inspect ngconf 查看卷的详细的信息
我现在删除容器,卷不会删除,
但是我重启容器后,任然还是原来的卷的数据
docker 网络
容器和容器之间进行访问
docker run -d --name app01 nginx
docker run -d --name app02 nginx
docker ps 可以看到两个container启动
进入容器01,可以看到通过curl http://ip:端口进行访问
ip a,就可以看到docker的网络
docker container inspect app01 #可以查看详情的信息,可以看到IP
docker每启动都会给每个容器分配一个唯一的IP,使用容器+端口就可以互相访问
会出现一种情况,就是容器删除了,但是IP变化了,就会出现无法正常的使用原IP进行访问
解决方法:
我们可以使用进行域名
自己创建一个网络,在这个网络中,容器的名字就可以当做容器的域名
docker0默认不支持域名
创建网络
docker network create mynet
docker network ls 查看网络
docker run -d --name app01 --network mynet nginx
--network mynet 格式
curl htp://app01:80 就可以完成访问
mysql容器启动
启动一个mysql容器
docker run -d -p 3306:3306 \
-v /app/myconf:/etc/mysql/conf.d \
-v /app/mydata:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:8.0.37-debian
其中-e 是环境变量,docker hub上可以查到相关组件的环境配置
wordpress博客系统启动
docker run -d -p 8080:80 、
-e WORDPRESS_DB_HOST=mysql \
-e WORDPRESS_DB_USER=root \
-e WORDPRESS_DB_PASSWORD=123456 \
-e WORDPRESS_DB_NAME=wordpress \
-v wordpress:/var/www/html \
--restart always \
--name myblog \
--network blog \
wordpress:latest
相关的参数也是查看docker hub上的官方文档
docker compose
批量化管理容器的,可以批量化启动,删除,停止多个容器
简单的来说就是在一个文件内写多个docker run,并做好配置实现一键启动
docker compose up -d 上线
docker compose down 下线
docker compose start xx xx xx 启动多个容器
docekr compose stop xxxx 停止容器
docker compose scale xx=3 某个程序启动3份
compose 语法
文件名统一命名为,xxxxx.yaml
参考官方的语法文档
<https://docs.docker.com/compose/compose-file/>
顶级元素
name 名字
services 服务
networks 网络
volumes 卷
configs 配置
secrets 密钥
compose.yaml
包含启动mysql和blog
name: myblog
services:
mysql:
container_name: mysql
images: mysql:8.0
posrts:
- "3306:3306"
enviornment:
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_DATABASE=wordpress
volumes:
- mysql-data:/var/lib/mysql
- /app/myconf:/etv/mysql/conf.d
restart: always
networks:
- blog
wordpress:
images: wordpress
ports:
- "8080:80"
environment:
- WORDPRESS_DB_HOST=mysql
- WORDPRESS_DB_USER=root
- WORDPRESS_DB_PASSWORD=123456
- WORDPRESS_DB_NAME=wordpress
volumes:
- wordpress:/var/www/html
restart: always
networks:
- blog
depends_on:
- mysql
volumes:
mysql-data:
wordprsss:
networks:
blogs:
docker compose -f compose.yaml up -d 指定启动文件和后台运行
某一天我修改了一个容器的配置后执行
docker compose -f composeyaml up -d 就会重新启动那些修改了的容器,未改变的不动
docker compose down 下线,但是卷没有删除还在
docker compose -f compose.yaml down --rmi all或者某个 -v 移除的时候附带移除镜像和卷
镜像制作
dockerfile #编写镜像
docker bulid #构建
镜像包含基础的环境,软件包,启动的命令
详细参考官网
<https://docs.docker.com/reference/dockerfile/>
FROM 指定镜像基础环境
RUN 运行自定义命令
CMD 容器启动命令或参数
LABEL 自定义标签
EXPOSE 指定暴露的端口
ENV 环境变量
ADD 添加文件到镜像
COPY 复制文件到镜像
ENTRYPOINT 容器固定命令
VOLUME 数据卷
USER 指定用户和用户组
WORKDIR 指定默认工作目录
ARG 指定构建参数
vim Dockerfile
docker bulid -f Dockerfile -t myjavaapp:v1.0 .
docker images 可以看到
docker 镜像分层存储机制