Docker 从入门到项目部署教学文档

发布于:2025-03-31 ⋅ 阅读:(13) ⋅ 点赞:(0)

一、引言

在当今的软件开发与运维领域,快速、高效地部署和管理应用是至关重要的。Docker 作为一款强大的容器化技术工具,能够帮助开发者和运维人员轻松构建、运行和管理应用,极大地提高工作效率。本教学文档将深入介绍 Docker 的相关知识,涵盖从基础概念到项目部署的全流程,助力读者快速掌握 Docker 技术并应用于实际工作中。

二、Docker 基础概念

(一)镜像(Image)

  1. 定义:将应用所需的函数库、依赖、配置等与应用一起打包得到的文件包。镜像包含了应用运行所需要的完整环境,包括操作系统、系统函数库、应用程序及其配置等,它是创建容器的基础。
  2. 命名规范:镜像名称一般由两部分组成:[repository]:[tag]。其中repository是镜像名,tag是镜像的版本。若未指定tag,默认是latest,代表最新版本的镜像,例如mysql:5.7mysqlrepository5.7tag

(二)容器(Container)

  1. 定义:为每个镜像的应用进程创建的隔离运行环境。容器基于镜像创建,是镜像的运行实例,多个容器可以共享同一个镜像。容器之间相互隔离,拥有独立的文件系统、网络环境和进程空间,保证了应用运行的独立性和安全性。
  2. 与镜像的关系:镜像是静态的文件包,用于创建容器;容器是镜像的动态运行实例,通过运行镜像来启动容器,容器中的应用在隔离环境中运行,与宿主机和其他容器相互隔离。

(三)镜像仓库(Registry)

  1. 定义:存储和管理镜像的服务平台。它提供了镜像的存储、分发和共享功能,方便用户获取和使用各种镜像。
  2. Docker Hub:目前最大的公共镜像仓库,包含了各种常见的应用镜像,如mysqlnginxjava等。用户可以在 Docker Hub 上搜索、下载和上传镜像,也可以基于官方镜像进行定制和扩展。

三、部署 MySQL

(一)传统方式安装 MySQL 的痛点

在传统的 Linux 系统中安装 MySQL,需要执行一系列复杂的操作,包括卸载系统自带的 MySQL 相关组件(如mariadb-libs)、下载 MySQL 安装包(从官网选择合适的版本和操作系统类型)、解压缩安装包、安装依赖包(如net-toolsopenssl-devel等)、安装 MySQL 服务等。这个过程涉及众多命令,安装包的下载和依赖处理也较为繁琐,容易出错,且安装过程耗时较长。

(二)使用 Docker 部署 MySQL

  1. 前提条件:确保虚拟机已经安装 Docker,且网络连接正常。
  2. 部署命令
docker run -d \
  --name mysql \
  -p 3306:3306 \ 
  -e TZ=Asia/Shanghai \
  -e MYSQL_ROOT_PASSWORD=123 \
  mysql
  1. 命令解读
    • docker run创建并运行一个容器。
    • -d:让容器在后台运行,不占用当前终端的输入输出,用户可以继续在终端执行其他命令。
    • --name mysql:给容器起名为mysql,容器名在当前 Docker 环境中必须唯一,方便后续对该容器进行管理和操作。
    • -p 3306:3306:设置端口映射,将宿主机的 3306 端口映射到容器内的 3306 端口。这样,外部应用就可以通过宿主机的 3306 端口访问容器内的 MySQL 服务。
    • -e TZ=Asia/Shanghai:设置容器内的时区为上海时区,确保时间相关的操作和应用逻辑正常运行。
    • -e MYSQL_ROOT_PASSWORD=123:设置 MySQL 的 root 用户密码为123,用于登录 MySQL 数据库。
    • mysql:指定运行的镜像名称,这里使用的是 Docker Hub 上的官方mysql镜像,若本地没有该镜像,Docker 会自动从 Docker Hub 下载。

四、Docker 常见命令

(一)镜像操作命令

  1. docker pull:从镜像仓库拉取镜像到本地。例如,拉取nginx镜像:docker pull nginx
  2. docker push:将本地镜像推送到镜像仓库,需要先登录到镜像仓库。
  3. docker images:查看本地已有的镜像列表,显示镜像的名称、标签、镜像 ID、创建时间和大小等信息。
  4. docker rmi:删除本地指定的镜像,例如docker rmi nginx:latest删除本地的nginx:latest镜像。

(二)容器操作命令

  1. docker run:创建并运行容器,前面部署 MySQL 时已详细介绍。
  2. docker stop:停止运行中的容器,例如docker stop mysql停止名为mysql的容器。
  3. docker start:启动已停止的容器,docker start mysql启动名为mysql的容器。
  4. docker ps:查看当前正在运行的容器列表,显示容器的 ID、名称、运行状态、创建时间、端口映射等信息。加上-a参数可以查看所有容器(包括已停止的容器)。
  5. docker rm:删除指定的容器,容器必须是停止状态才能删除,例如docker rm mysql删除名为mysql的容器。
  6. docker logs:查看容器的日志输出,帮助调试和监控容器内应用的运行情况,如docker logs mysql查看mysql容器的日志。
  7. docker exec:在运行中的容器内执行命令,例如docker exec -it mysql bashmysql容器内执行bash命令,进入容器的命令行界面,-it参数用于保持标准输入输出的交互性。

(三)数据卷操作命令

  1. docker volume create:创建数据卷,例如docker volume create my_volume创建名为my_volume的数据卷。
  2. docker volume ls:查看所有数据卷,显示数据卷的名称、驱动等信息。
  3. docker volume rm:删除指定的数据卷,docker volume rm my_volume删除名为my_volume的数据卷。
  4. docker volume inspect:查看某个数据卷的详细信息,包括数据卷的挂载点、驱动选项等。
  5. docker volume prune:清除未使用的数据卷,释放磁盘空间。

(四)网络操作命令

  1. docker network create:创建一个自定义网络,如docker network create my_network创建名为my_network的网络。
  2. docker network ls:查看所有网络,包括默认的bridge网络和自定义网络。
  3. docker network rm:删除指定的网络,docker network rm my_network删除名为my_network的网络。
  4. docker network prune:清除未使用的网络。
  5. docker network connect:使指定容器连接加入某网络,docker network connect my_network mysqlmysql容器连接到my_network网络。
  6. docker network disconnect:使指定容器连接离开某网络。
  7. docker network inspect:查看网络的详细信息,包括网络的子网、网关、连接的容器等。

五、数据卷(Volume)

(一)数据卷的概念

数据卷是一个虚拟目录,它是容器内目录与宿主机目录之间映射的桥梁。通过数据卷,可以方便地在宿主机和容器之间共享数据,实现对容器内文件的操作和数据的持久化存储,即使容器被删除,数据卷中的数据依然存在。

(二)数据卷的使用场景

  1. 容器内文件操作:在容器运行过程中,需要修改容器内的配置文件或数据文件时,可以通过数据卷将宿主机的目录挂载到容器内,直接在宿主机上进行修改,容器内的文件也会同步更新。
  2. 数据持久化:对于一些有数据存储需求的应用,如数据库,将数据目录挂载到数据卷上,保证数据不会因为容器的重启或删除而丢失。

(三)挂载数据卷的方法

在执行docker run命令时,使用-v参数进行数据卷挂载,格式为-v 数据卷名:容器内目录-v 本地目录:容器内目录。当创建容器时,如果挂载的数据卷不存在,Docker 会自动创建数据卷。例如,将宿主机的/root/mysql/data目录挂载到mysql容器内的/var/lib/mysql目录:

docker run -d \
  --name mysql \
  -p 3306:3306 \
  -e TZ=Asia/Shanghai \
  -e MYSQL_ROOT_PASSWORD=123 \
  -v /root/mysql/data:/var/lib/mysql \
  mysql

(四)案例 - 利用 Nginx 容器部署静态资源

  1. 需求:创建 Nginx 容器,修改容器内html目录下的index.html文件内容,并将静态资源部署到 Nginx 的html目录。
  2. 步骤
    • 创建数据卷:docker volume create nginx_volume
    • 创建 Nginx 容器并挂载数据卷:
docker run -d \
  --name nginx \
  -p 80:80 \
  -v nginx_volume:/usr/share/nginx/html \
  nginx
  • 在宿主机上找到数据卷对应的目录(可通过docker volume inspect nginx_volume查看挂载点),在该目录下创建或修改index.html文件,容器内的/usr/share/nginx/html/index.html文件会同步更新。
  • 将静态资源拷贝到数据卷对应的目录,即可完成静态资源的部署。

(五)案例 - mysql 容器的数据挂载

  1. 需求:基于宿主机目录实现 MySQL 数据目录、配置文件、初始化脚本的挂载。
  2. 步骤
    • 挂载数据目录:-v /root/mysql/data:/var/lib/mysql,将宿主机的/root/mysql/data目录挂载到容器内的/var/lib/mysql目录,用于存储 MySQL 的数据文件。
    • 挂载配置文件目录:-v /root/mysql/conf:/etc/mysql/conf.d,将宿主机的/root/mysql/conf目录挂载到容器内的/etc/mysql/conf.d目录,用于存放 MySQL 的配置文件。
    • 挂载初始化脚本目录:-v /root/mysql/init:/docker-entrypoint-initdb.d,将宿主机的/root/mysql/init目录挂载到容器内的/docker-entrypoint-initdb.d目录,并在该目录下放置初始化 SQL 脚本,容器启动时会自动执行这些脚本。
      完整的docker run命令如下:
docker run -d \
  --name mysql \
  -p 3306:3306 \
  -e TZ=Asia/Shanghai \
  -e MYSQL_ROOT_PASSWORD=123 \
  -v /root/mysql/data:/var/lib/mysql \
  -v /root/mysql/conf:/etc/mysql/conf.d \
  -v /root/mysql/init:/docker-entrypoint-initdb.d \
  mysql

六、自定义镜像

(一)自定义镜像的概念

自定义镜像就是根据用户的需求,将应用程序、程序运行的系统函数库、运行配置等文件打包成一个镜像。通过自定义镜像,可以将应用及其运行环境封装在一起,方便在不同的环境中部署和运行。

(二)构建自定义镜像的步骤

以部署 Java 应用为例:

  1. 准备 Linux 运行环境:可以选择基于ubuntucentos等基础镜像来构建。
  2. 安装 JRE 并配置环境变量:在选择的基础镜像中安装 Java 运行时环境(JRE),并配置JAVA_HOME等环境变量,确保 Java 应用能够正常运行。
  3. 拷贝 Jar 包:将开发好的 Java 应用的 Jar 包拷贝到镜像中的指定目录。
  4. 编写运行脚本:编写一个启动脚本,用于在容器启动时运行 Java 应用,例如java -jar xx.jar

(三)Dockerfile 的使用

  1. Dockerfile 的概念:Dockerfile 是一个文本文件,其中包含一个个的指令(Instruction),用指令来说明要执行什么操作来构建镜像。Docker 可以根据 Dockerfile 自动构建镜像。
  2. 常见指令
    • FROM:指定基础镜像,例如FROM centos:6centos:6为基础镜像构建新镜像。
    • ENV:设置环境变量,可在后面指令使用,如ENV JAVA_DIR=/usr/local设置 Java 的安装目录环境变量。
    • COPY:拷贝本地文件到镜像的指定目录,COPY ./jre11.tar.gz /tmp将本地的jre11.tar.gz文件拷贝到镜像的/tmp目录。
    • RUN:执行 Linux 的 shell 命令,一般用于安装过程的命令,如RUN tar -zxvf /tmp/jre11.tar.gz && EXPORTS path=/tmp/jre11:$path解压 JRE 安装包并配置环境变量。
    • EXPOSE:指定容器运行时监听的端口,是给镜像使用者看的,EXPOSE 8080表示容器内的应用监听 8080 端口。
    • ENTRYPOINT:镜像中应用的启动命令,容器运行时调用,ENTRYPOINT java -jar xx.jar设置 Java 应用的启动命令。

(四)案例 - 构建 Java 镜像

  1. 基于 Ubuntu 基础镜像构建 Java 镜像
# 指定基础镜像
FROM ubuntu:16.04
# 配置环境变量,JDK的安装目录、容器内时区
ENV JAVA_DIR=/usr/local
# 拷贝jdk和java项目的包
COPY ./jdk8.tar.gz $JAVA_DIR/
COPY ./docker-demo.jar /tmp/app.jar
# 安装JDK
RUN cd $JAVA_DIR \
  && tar -xf ./jdk8.tar.gz \
  && mv ./jdk1.8.0_144 ./java8
# 配置环境变量
ENV JAVA_HOME=$JAVA_DIR/java8
ENV PATH=$PATH:$JAVA_HOME/bin
# 入口,java项目的启动命令
ENTRYPOINT ["java", "-jar", "/app.jar"]
  1. 基于 JDK 基础镜像构建 Java 镜像(简化步骤)
# 基础镜像
FROM openjdk:11.0-jre-buster
# 拷贝jar包
COPY docker-demo.jar /app.jar
# 入口
ENTRYPOINT ["java", "-jar", "/app.jar"]
  1. 构建镜像:编写好 Dockerfile 后,在包含 Dockerfile 的目录下执行以下命令构建镜像:
docker build -t myImage:1.0 .

-t参数给镜像起名,格式为repository:tag,不指定tag时默认为latest;最后的.表示 Dockerfile 所在目录为当前目录。

七、容器网络

(一)默认网络模式

默认情况下,所有容器都是以bridge方式连接到 Docker 的一个虚拟网桥上,如docker0。每个容器在该网络中都有一个独立的 IP 地址,容器之间可以通过 IP 地址进行通信,但无法通过容器名直接访问。例如,容器 A 的 IP 地址是172.17.0.2,容器 B 的 IP 地址是172.17.0.3,容器 A 可以通过172.17.0.3访问容器 B,但不能通过容器 B 的名称访问。

(二)自定义网络

加入自定义网络的容器才可以通过容器名互相访问。使用自定义网络可以更好地管理容器之间的通信和隔离,提高容器网络的灵活性和安全性。

  1. 创建自定义网络docker network create my_network创建名为my_network的自定义网络。
  2. 将容器加入自定义网络:在创建容器时,使用--network参数将容器加入自定义网络,例如:
docker run -d \
  --name mysql \
  -p 3306:3306 \
  -e TZ=Asia/Shanghai \
  -e MYSQL_ROOT_PASSWORD=123 \
  --network my_network \
  mysql

这样,加入my_network网络的其他容器就可以通过mysql这个容器名访问该 MySQL 容器。

八、项目部署

(一)部署 Java 应用

  1. 需求:将课前资料提供的hmall项目打包为镜像并部署,镜像名hmall
  2. 步骤
    • 编写hmall项目的 Dockerfile,根据项目的依赖和运行要求,选择合适的基础镜像,安装相关依赖,拷贝项目 Jar 包,设置启动命令。例如:
FROM openjdk:11.0-jre-buster
COPY hmall.jar /app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
  • 构建hmall镜像:在包含 Dockerfile 的目录下执行docker build -t hmall:1.0 .
  • 运行hmall容器:
docker run -d \
  --name hmall \
  -p 8080:8080 \
  hmall:1.0

上述命令将hmall镜像运行在容器中,并将容器的 8080 端口映射到宿主机的 8080 端口,外部可通过宿主机的 8080 端口访问hmall应用。

(二)部署前端

  1. 需求:创建一个新的 Nginx 容器,将课前资料提供的nginx.confhtml目录与容器挂载。
  2. 步骤
    • 确保有nginx.conf配置文件和html目录,其中html目录包含前端页面文件。
    • 运行 Nginx 容器并挂载文件:
docker run -d \
  --name nginx \
  -p 80:80 \
  -v /path/to/nginx.conf:/etc/nginx/nginx.conf \
  -v /path/to/html:/usr/share/nginx/html \
  nginx

/path/to/nginx.conf替换为本地nginx.conf文件的路径,/path/to/html替换为本地html目录的路径。这样,Nginx 容器会使用挂载的配置文件和前端页面文件对外提供服务。

(三)使用 Docker Compose 进行多容器部署

  1. Docker Compose 概述:Docker Compose 通过一个单独的docker-compose.yml模板文件(YAML 格式)来定义一组相关联的应用容器,帮助实现多个相互关联的 Docker 容器的快速部署。它可以管理容器的创建、启动、停止、重启等操作,还能处理容器之间的依赖关系、网络配置和数据卷挂载等。
  2. docker-compose.yml文件示例
version: "3.8"
services:
  mysql:
    image: mysql
    container_name: mysql
    ports:
      - "3306:3306"
    environment:
      TZ: Asia/Shanghai
      MYSQL_ROOT_PASSWORD: 123
    volumes:
      - "./mysql/conf:/etc/mysql/conf.d"
      - "./mysql/data:/var/lib/mysql"
      - "./mysql/init:/docker-entrypoint-initdb.d" 
    networks:
      - hm-net
  hmall:
    build:
       context: .
       dockerfile: Dockerfile
    container_name: hmall
    ports:
      - "8080:8080"
    networks:
      - hm-net
    depends_on:
      - mysql
  nginx:
    image: nginx
    container_name: nginx
    ports:
      - "18080:18080"
      - "18081:18081"
    volumes:
      - "./nginx/nginx.conf:/etc/nginx/nginx.conf"
      - "./nginx/html:/usr/share/nginx/html"
    depends_on:
      - hmall
    networks:
      - hm-net
networks:
  hm-net:
    name: hmall
  • version指定 Compose 文件的版本。
  • services部分定义各个服务(容器)。
    • mysql服务使用mysql镜像,设置端口映射、环境变量、数据卷挂载和网络配置,mysql服务依赖于hm - net网络。
    • hmall服务通过build指定构建镜像的上下文和 Dockerfile,设置端口映射、网络配置和依赖关系,hmall依赖于mysql服务,即会在mysql启动后再启动。
    • nginx服务使用nginx镜像,设置端口映射、数据卷挂载、依赖关系和网络配置,nginx依赖于hmall服务。
  • networks部分定义自定义网络hm - net,并设置其别名为hmall
  1. Docker Compose 常用命令
    • docker compose up:创建并启动所有服务容器。如果镜像不存在,会自动拉取或构建。加上-d参数可在后台运行。
    • docker compose down:停止并移除所有容器、网络,清理相关资源。
    • docker compose ps:列出所有启动的容器。
    • docker compose logs:查看指定容器的日志,例如docker compose logs hmall查看hmall容器的日志。
    • docker compose stop:停止容器。
    • docker compose start:启动容器。
    • docker compose restart:重启容器。
    • docker compose top:查看运行的进程。
    • docker compose exec:在指定的运行中容器中执行命令,如docker compose exec hmall bashhmall容器中执行bash命令进入容器内部。

九、总结

(一)Docker 的优势

  1. 快速部署:通过镜像和容器技术,能快速创建和启动应用,大大缩短部署时间,提高开发和运维效率。
  2. 环境一致性:确保应用在不同环境(开发、测试、生产)中运行环境一致,减少因环境差异导致的问题。
  3. 资源隔离:容器之间相互隔离,保证应用的独立性和安全性,同时合理利用系统资源。
  4. 易于扩展和管理:方便添加、删除和更新容器,通过 Docker Compose 可轻松管理多个相关容器的部署和运维。

(二)学习建议

  1. 多实践:通过实际操作各种案例,如部署不同类型的应用、使用数据卷和自定义网络等,加深对 Docker 概念和命令的理解。
  2. 阅读官方文档:官方文档提供了详细的命令说明、最佳实践和技术细节,是深入学习 Docker 的重要资源。
  3. 参与社区:关注 Docker 社区,参与讨论和交流,获取最新的技术动态和解决方案,与其他开发者共同学习和进步。