Docker入门指南(二):核心操作与项目部署实战

发布于:2025-08-09 ⋅ 阅读:(17) ⋅ 点赞:(0)

一、Docker基础

DOcker最常见的命令就是操作镜像容器的命令,详见官方文档:https://docs.docker.com/
tip:使用 docker xx --help 命令查看docker xx命令的语法
在这里插入图片描述
容器生命周期
在这里插入图片描述
容器三个状态

  • 运行:进程正常运行
  • 暂停:进程暂停,CPU不再运行,不释放内存
  • 停止:进程终止,回收进程占用的内存、CPU等资源。

常见命令

操作对象 命令 作用 例子
镜像 docker images 查看本地所有镜像 -
- docker rmi 镜像名:版本 删除镜像 docker rmi mysql:8.0
- docker save -o 文件名 镜像名 把镜像存为压缩包 docker save -o nginx.tar nginx:latest
- docker load -i 文件名 从压缩包恢复镜像 docker load -i nginx.tar
容器 docker ps -a 查看所有容器(添加-a参可展示所有容器(包括挂掉的容器)) -
- docker run xx 运行一个容器 -
- docker pause xx 让一个运行的容器暂停
- docker unpause xx 让一个容器从暂停的状态恢复运行
- docker stop xx 停止一个运行的容器 -
- docker logs -f 容器名 实时查看容器日志 docker logs -f mysql
- docker exec -it 容器名 bash 进入容器内部 docker exec -it nginx bash
- docker rm -f 容器名 强制删除容器(无论是否运行,添加 -f 参数可以强制删除) docker rm -f nginx

常见容器命令演示

  • docker run:创建并运行一个容器,处于运行状态
  • docker pause xx:让一个运行的容器暂停
  • docker unpause xx:让一个容器从暂停的状态恢复运行
  • docker stop xx:停止一个运行的容器
  • docker start xx:让一个停止的容器再次运行
  • docker rm xx:删除一个容器(不能删除正在运行中的容器),添加 -f 参数可以强制删除
  • docker logs xx容器名 查看容器日志命令,添加 -f 参数可以持续查看日志
  • docker ps 查看运行中的容器,添加-a参可展示所有容器(包括挂掉的容器)。加上–format参数可以用指定格式查看

案例:进入nginx容器,修改 html 文件,添加 Welcome to My Blog!

1. 进入nginx容器

docker exec -it nginx bash
  • -it:给当前进入的容器创建一个标准输入、输出终端,允许我们与容器交互
  • nginx:要进入的容器的名称
  • bash:进入容器后执行的命令,bash是一个Linux终端交互命令

2. 进入nginx的html所在的目录

查看DockerHub网站中nginx页面,可以知道nginx的html位置在 /usr/share/nginx/html

## 进入目录
cd /usr/share/nginx/html
## 查看文件
ls
>> 50x.html index.html
## 修改文件,容器内没有vi命令,无法直接修改,会报错
vi index.html
>> error. command not found

## 可使用以下命令进行修改(但不推荐)
sed -i -e 's#Welcome to nginx#Welcome To My Blog#g' index.html

访问 虚拟机ip:80(80端口可以不写),即可看到结果

Q:目前存在的问题,数据与容器耦合度较高

  • 容器没有提供vi命令,不能直接编辑,修改起来需要进入容器内部比较麻烦。
  • 在容器内的修改对外是不可见的,所有修改对新创建的容器是不可复用的
  • 升级维护困难:数据在容器内,如果要升级容器必然删除旧容器,所有数据也删除掉了。这是因为容器内的数据默认是临时的,想让数据永久保存,就得用数据卷。

二、数据卷

什么是数据卷?
数据卷是一个虚拟目录,它将宿主机目录映射到容器内目录,方便我们操作容器内文件,或者方便迁移容器产生的数据。
简单说,数据卷是宿主机和容器之间的共享文件夹

  • 你在宿主机的这个文件夹里操作,容器内对应的目录会同步变化;
  • 就算容器删了,宿主机的文件还在,重新挂载后数据能恢复。

如何挂载数据卷?
在这里插入图片描述
在执行docker run命令创建容器时,利用-v 数据卷名:容器内目录完成挂载。容器创建时,如果发现挂载的数据卷不存在时,会自动创建。
一旦完成数据卷挂载,对容器的一切操作都会对应作用在宿主机目录了,这样操作宿主机的**/var/lib/docker/volumes/html目录就相当于操作容器内的/usr/share/nginx/html**目录。
docker volumn --help 查看具体有哪些命令

数据卷的常见命令有哪些?

  • docker volume create app-data: 创建一个volume:app-data
  • docker volume ls: 查看数据卷
  • docker volume rm app-data: 删除数据卷
  • docker volume inspect app-data: 查看数据卷详情
  • docker volume prune: 删除未使用的数据卷
  • docker run -v app-data:/app nginx 挂载数据卷

案例1:利用Nginx容器部署静态资源

需求:创建Nginx容器,修改nginx容器内的html目录下的 index.html 文件内容,将静态资源部署到nginx的html目录

# 数据卷html挂载到容器内的html目录
docker run --name nginx -v html:/usr/share/nginx/html -p 80:80 -d nginx
# 查看数据卷位置  找到"Mountpoint"字段,比如/var/lib/docker/volumes/html/_data
docker volume inspect html 
# 进入该目录
cd /var/lib/docker/volumes/html/_data
# 修改文件
vi index.html

在这里插入图片描述

案例2:mysql容器的数据挂载

容器不仅仅可以挂载数据卷,也可以直接挂载到宿主机目录

  • 带数据卷模式:宿主机目录 --> 数据卷 —>容器内目录
  • 直接挂载模式:宿主机目录 --> 容器内目录
    在这里插入图片描述

数据卷挂载 VS 目录直接挂载

方式 优点 缺点 适合场景
数据卷挂载 耦合度低,Docker 自动管理,路径安全 宿主机路径深,不好找 长期使用的服务
宿主机目录挂载 路径直观,方便手动操作 耦合度高,需自己管理目录权限 开发环境、临时测试

需求: 基于宿主机目录实现MySQL数据目录、配置文件、初始化脚本的挂载(查阅官方镜像文档)
提示:在执行docker run命令时,使用-v 本地目录:容器内目录 可以完成本地目录挂载
本地目录必须以"/" 或"./"开头,如果直接以名称开头,会被识别为数据卷而非本地目录

  • -V mysql:/var/ib/mysql 会被识别为一个数据卷叫mysq|
  • -V ./mysql:/var/lib/mysql 会被识别为当前目录下的mysqI目录

查阅资料可知,mysql容器内conf目录位置是 /etc/mysql/conf.d;容器内存储数据的目录是:/var/lib/mysql

docker pull mysql
# 在宿主机创建文件夹
mkdir -p /tmp/mysql/data /tmp/mysql/conf

# 启动MySQL时挂载这两个目录
docker run -d --name mysql \
-p 3307:3306 \
-e TZ=Asia/shanghai \
-e MYSQL_ROOT_PASSWORD=root \
-v /tmp/mysql/data:/var/lib/mysql \
-v /tmp/mysql/conf:/etc/mysql/conf.d \
 mysql

三、自定义镜像:把你的应用打包成“安装包”

如果想让自己写的程序(比如 Java、Python 应用)也能一键运行,就需要把它打包成 Docker 镜像。

镜像的结构是怎样的?
镜像中包含了应用程序所需要的运行环境、函数库、配置、以及应用本身等各种文件,这些文件分层打包而成。
Dockerfile是做什么的?
Dockerfile是一个文本文件,利用简单固定的指令描述镜像的结构和构建过程,这样Docker才可以依次来构建镜像
构建镜像的命令是什么?
docker build -t 镜像名 Dockerfile目录

Dockerfile核心指令

指令 说明 示例
FROM 指定基础镜像 FROM openjdk:11
ENV 设置环境变量 ENV key value
COPY 复制文件,拷贝本地文件到镜像的指定目录 COPY ./jre11.tar.gz /tmp
RUN 执行Linux的shell命令,一般是 安装过程的命令 RUN apt-get update
EXPOSE 指定容器运行时监听的端口,是给镜像使用者看的 EXPOSE 8080
ENTRYPOINT 镜像中应用的启动命令,容器运行时调用 ENTRYPOINT java -jar xx.jar

我们可以基于Ubuntu基础镜像,利用Dockerfile描述镜像结构, 也可以直接基于JDK为基础镜像,省略前面的步骤:

案例:基于Java8构建Java项目

1. 准备工作

  • 把你的 Java 项目打包成app.jar,放在/tmp/myapp目录下;
  • 在同一目录创建Dockerfile(文件名固定)。

2. 编写 Dockerfile

# 1. 基于Java8环境(相当于“操作系统+Java”)
FROM openjdk:8

# 2. 把宿主机的app.jar拷贝到容器里
COPY ./app.jar /tmp/app.jar

# 3. 声明应用运行的端口
EXPOSE 8080

# 4. 容器启动时执行的命令(启动Java程序)
ENTRYPOINT ["java", "-jar", "/tmp/app.jar"]

3. 构建并运行镜像

# 进入Dockerfile所在目录,构建镜像
docker build -t myapp:1.0 .  # 镜像名:版本  点表示当前目录

# 启动容器
docker run -d \
  --name myapp \
  -p 8080:8080 \
  myapp:1.0

访问宿主机IP:8080,就能看到你的应用了。

tip:

  • Dockerfile的第一行必须是FROM,从一个基础镜像来构建
  • 基础镜像可以是基本操作系统,如Ubunut,也可以是其他人制作好的镜像,例如openjdk:8、java:8-alpine

四、容器网络:互联互通

默认网络模型:
在这里插入图片描述

网络常见命令

命令 说明
docker network create 创建一个网络
docker network ls 查看所有网络
docker network rm 删除指定网络
docker network prune 清除未使用的网络
docker network connect 使指定容器连接加入某网络
docker network di sconnect 使指定容器连接离开某网络
docker network inspect 查看网络详细信息

自定义网络示例

# 创建网络
docker network create app-net

# 容器加入网络
docker run -d --name mysql --network app-net mysql
docker run -d --name app --network app-net my-app:1.0

网络优势

  • 容器间通过名称直接访问
  • 网络隔离更安全
  • 避免端口冲突

DockerCompose:一键启动多个关联容器

实际项目中,一个应用往往需要多个服务(比如 Java 后端 + MySQL+Redis)。手动一个个启动太麻烦,用Docker Compose可以一键搞定。

docker compose的命令格式如下:

docker compose [OPTIONS] [COMMAND]

类型 参数或指令 说明
Options -f 指定compose文件的路径和名称
- -p 指定project名称
Commands up 创建并启动所有service容器
- down 停止并移除所有容器、网络
- ps 列出所有启动的容器
- logs 查看指定容器的日志
- stop 停止容器
- start 启动容器
- restart 重启容器
- top 查看运行的进程
- exec 在指定的运行中容器中执行命令

核心用法:写个docker-compose.yml配置文件
示例:启动 Java 应用 + MySQL
创建docker-compose.yml

version: "3.8"  # 固定格式

services:
  # MySQL服务
  mysql:
    image: mysql:8.0  # 用官方MySQL镜像
    environment:
      MYSQL_ROOT_PASSWORD: 123456  # 数据库密码
    volumes:
      - /tmp/mysql/data:/var/lib/mysql  # 挂载数据目录

  # 你的Java应用服务
  myapp:
    build: ./myapp  # 从./myapp目录的Dockerfile构建镜像
    ports:
      - "8080:8080"  # 端口映射
    depends_on:
      - mysql  # 先启动MySQL再启动应用
    environment:
      # 连接MySQL时,用服务名“mysql”当主机名(Docker内部自动解析)
      SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/mydb

启动和停止命令

# 启动所有服务(在yml文件所在目录)
docker compose up -d  # -d表示后台运行

# 停止并删除所有服务(数据不会丢,因为挂载了卷)
docker compose down

docker compose ps     # 查看服务状态
docker compose logs   # 查看日志

上述的Compose文件描述一个项目,其中包含两个容器:

  • mysql:基于mysql:5.7.25 镜像构建的容器,并且挂载了两个项目
  • web: 基于docker:build 临时构建的镜像容器,映射端口为8090

利用DockerCompose部署微服务集群

  1. 准备dockercompose文件
  2. 修改项目配置,将数据库、nacos地址都命名为docker-compose中的服务名
  3. 使用maven打包工具,将项目中的每个微服务都打包为app.jar
  4. 将cloud-demo上传至虚拟机,利用docker-compose up -d 来部署

五、镜像仓库:存镜像的 “云盘”

镜像仓库就像 “应用商店”,用来存放你构建的镜像,方便在不同机器上使用。
1. 公共仓库(直接用)

  • Docker Hub:官方仓库,有各种现成镜像(如mysql、nginx);
  • 阿里云镜像仓库:国内访问快,可搜 “阿里云镜像服务” 获取加速地址。

2. 推送自己的镜像到仓库(可选)
如果想分享自己的镜像,步骤如下:

# 1. 给镜像打标签(仓库地址/镜像名:版本)
docker tag myapp:1.0 你的仓库地址/myapp:1.0

# 2. 推送镜像
docker push 你的仓库地址/myapp:1.0

# 3. 在其他机器拉取
docker pull 你的仓库地址/myapp:1.0

常见问题解决

1. 容器无法访问外部网络

# 检查DNS配置
docker run --rm busybox nslookup google.com

# 解决方案:自定义DNS
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "dns": ["8.8.8.8", "114.114.114.114"]
}
EOF

2. 端口冲突处理

# 查找占用端口进程
sudo lsof -i :8080

# 解决方案:
# 1. 停止冲突进程
# 2. 修改容器映射端口:-p 8081:8080

3. 存储空间清理


# 删除所有停止的容器
docker container prune

# 删除未使用的镜像
docker image prune -a

# 删除未使用的数据卷
docker volume prune

总结:这篇的核心知识点

  • 命令:掌握镜像和容器的增删查改,docker exec进入容器;
  • 数据卷:用-v挂载数据,避免容器删除导致数据丢失;
  • 自定义镜像:用 Dockerfile 打包自己的应用,实现 “一次构建,到处运行”;
  • Docker Compose:通过docker-compose.yml管理多个服务,一键启动集群。

网站公告

今日签到

点亮在社区的每一天
去签到