缘博客
发布日期

Docker(一):从手工安装到镜像、容器与常用命令

作者
  • 姓名
    社交账号

本篇学习范围

Docker 的价值不只是“少敲几条命令”。它把应用、依赖、运行配置打成镜像,再用容器提供隔离的运行环境,让同一套应用能以更稳定的方式交付和管理。

这篇会完整覆盖课件的第一条主线:

传统 Linux 安装 MySQL
为什么步骤多、依赖多、容易出错
镜像、容器、镜像仓库与 Docker daemon
docker run 快速启动 MySQL
镜像与容器的查询、启动、停止、进入、导入导出

后两篇再处理数据持久化、Dockerfile、网络,以及 Java / Nginx / Compose 项目部署。


为什么会需要 Docker:先看一次传统 MySQL 安装

课件先回顾了在 CentOS 7 上手动安装 MySQL 的过程。目的不是要求现在照着部署,而是让我们看到传统交付会同时碰到软件包、依赖、用户权限、数据目录、环境变量和系统服务等问题。

1. 查找并卸载系统自带的冲突包

rpm -qa | grep mysql
rpm -qa | grep mariadb

课件使用下面的形式删除 MariaDB 库:

rpm -e --nodeps mariadb-libs-5.5.60-1.el7_5.x86_64

这里的包版本必须以自己的 rpm -qa 输出为准。课件不同截图中甚至出现了不同的版本号,不能直接复制粘贴。

--nodeps 会忽略依赖关系强制卸载,容易让依赖该库的系统软件失效。它只适合明确知道影响范围的隔离练习环境;真实机器应先审查依赖,再决定是否移除。

2. 解压、移动并进入安装目录

课件示例使用 MySQL 8.0.30 的 Linux Generic 安装包:

tar -xvf mysql-8.0.30-linux-glibc2.12-x86_64.tar.xz
mv mysql-8.0.30-linux-glibc2.12-x86_64 /usr/local/mysql
cd /usr/local/mysql

这一步已经包含了“获取匹配平台的安装包、在正确路径解压、统一安装目录”的前置知识。不同版本、CPU 架构和系统库版本都会改变文件名,手工安装时需要人工判断。

3. 配置环境变量和系统服务

课件继续要求编辑全局环境变量:

vim /etc/profile
source /etc/profile

常见目标是把 MySQL 的 bin 目录放入 PATH,例如:

export PATH=/usr/local/mysql/bin:$PATH

然后把 MySQL 的启动脚本注册为系统服务:

cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysql
chkconfig --add mysql

/etc/init.dchkconfig 是课件的 CentOS 7 / SysV 兼容写法。采用现代 systemd 的系统通常应优先使用软件包提供的 service unit,并通过 systemctl 管理,而不是手工复制启动脚本。

4. 创建运行用户并初始化数据目录

groupadd mysql
useradd -r -g mysql -s /bin/false mysql
mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data

这些命令分别创建 mysql 用户组、不可登录的系统用户,并以该用户初始化数据目录。初始化输出的临时 root 密码需要妥善保存。

5. 启动、登录与改密码

systemctl start mysql
mysql -uroot -pxxxxx
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '1234';

-pxxxxx 中的 xxxxx 是初始化得到的临时密码,不是字面量。课件的 1234 仅用于课堂演示,不能作为真实环境密码,也不应把明文密码写入命令历史、脚本或 Git 仓库。

从这条链路可以看到:即使只为了“跑一个 MySQL”,也要处理系统差异、包版本、用户权限、服务注册、配置和密码。Docker 的作用就是把应用需要的运行环境和交付步骤收束到镜像与容器中。


Docker 的三个核心对象

镜像(image)

镜像是一个只读的应用文件包。它通常包含:

  • 应用程序本身;
  • 运行环境与系统函数库;
  • 默认配置;
  • 启动所需的命令或脚本。

镜像不是“正在运行的应用”。它更像一个可复用的交付模板。

容器(container)

Docker 根据镜像创建容器。每个容器都有隔离的进程、文件系统视图和网络命名空间,因此同一个 MySQL 镜像可以同时运行多个互不干扰的 MySQL 容器。

容器的可写层默认会随容器删除而消失。数据库、上传文件等需要长期保留的数据,要在下一篇通过数据卷或本地目录挂载解决。

镜像仓库(registry)

镜像仓库负责存储和分发镜像。Docker Hub 是官方维护的公共镜像仓库之一:

  • docker pull:从仓库拉取镜像到本地;
  • docker push:将本地镜像推送到仓库;
  • docker run:本地没有镜像时,会尝试从已配置的仓库拉取,再创建容器。

Client、Docker daemon 与仓库的关系

课件架构图表达的流程如下:

Docker Client 执行 docker run
Docker Host 上的 docker daemon 接收请求
本地无镜像时从 Registry 拉取镜像
daemon 使用本地 image 创建并运行 container

日常输入的是 Docker Client 命令,真正负责镜像、网络、容器和数据卷管理的是 Docker daemon。能够控制 Docker daemon 或访问 Docker socket 的账户拥有很高的系统权限,只应授予可信用户。


第一个 Docker 容器:运行 MySQL 8

课件的完整 MySQL 命令为:

docker run -d \
  --name mysql \
  -p 3307:3306 \
  -e TZ=Asia/Shanghai \
  -e MYSQL_ROOT_PASSWORD=123 \
  mysql:8

这条命令的含义:

片段作用
docker run创建并启动一个容器。
-d后台运行,终端不会持续占用。
--name mysql为容器指定唯一名称;同名容器存在时会报冲突。
-p 3307:3306将宿主机 3307 映射到容器内 MySQL 的 3306 端口。
-e TZ=Asia/Shanghai向镜像定义的容器环境传入时区变量。
-e MYSQL_ROOT_PASSWORD=123为官方 MySQL 镜像初始化 root 密码。
mysql:8要运行的镜像名与版本标签。

宿主机上访问这个数据库时,应该连接宿主机的 3307 端口。例如课件的远程连接形式是:

jdbc:mysql://192.168.100.128:3307

3306 是容器内端口,外部客户端没有直接进入容器网络时不能拿它替代宿主机映射端口。实际 JDBC URL 还通常需要数据库名和连接参数。

端口与密码的安全边界

-p 3307:3306 默认会发布到宿主机的所有网络接口。仅供本机开发时,可以限制为回环地址:

docker run -d \
  --name mysql \
  -p 127.0.0.1:3307:3306 \
  -e TZ=Asia/Shanghai \
  -e MYSQL_ROOT_PASSWORD='请替换为强随机密码' \
  mysql:8

课程中的 MYSQL_ROOT_PASSWORD=123 只用于示范参数。真实环境应使用强随机密码、受控的环境文件或 secrets,并结合防火墙与数据库账号权限限制访问范围。docker inspect 和进程环境可能暴露命令行传入的敏感值,因此不要把密码作为可长期保存的明文配置。


镜像名:repository:tag

镜像通常写作:

[repository]:[tag]

例如:

mysql:8
nginx:1.20.2

其中:

部分含义
repository镜像仓库中的名称。
tag标签,通常表示版本或变体。

未写 tag 时,Docker 默认使用 latest

docker pull mysql

等价于尝试拉取 mysql:latestlatest 只是一个可变标签,不是“永远稳定的最新版本”保证。课程演示和临时试验可以使用它,项目部署应固定明确版本,必要时固定镜像摘要(digest),以便复现与回滚。


常用命令:把镜像、容器和文件包串起来

课件的命令关系不是一张孤立清单,可以按对象与状态理解。

镜像仓库、本地镜像和镜像文件

Registry -- docker pull --> 本地镜像 -- docker push --> Registry
Dockerfile -- docker build --> 本地镜像
本地镜像 -- docker save --> 镜像 tar 文件
镜像 tar 文件 -- docker load --> 本地镜像
命令常见写法作用
docker pulldocker pull nginx:1.20.2从镜像仓库下载镜像。
docker pushdocker push 仓库/镜像:标签推送镜像到有权限的仓库。
docker imagesdocker images查看本地镜像列表。
docker rmidocker rmi 镜像名:标签删除本地镜像;仍被容器引用时通常需要先处理容器。
docker builddocker build -t my-image:1.0 .根据 Dockerfile 构建镜像,下一篇详讲。
docker savedocker save -o app.tar my-image:1.0导出一个或多个镜像为 tar 文件,适合离线传输。
docker loaddocker load -i app.tar从 tar 文件导入本地镜像。

docker save/load 保存的是镜像,不是正在运行容器里的临时改动,也不是数据库数据备份。

容器的两个常见状态

本地镜像 -- docker run --> 运行中容器
运行中 -- docker stop --> 已停止
已停止 -- docker start --> 运行中
已停止 -- docker rm --> 删除

相关命令:

命令常见写法说明
docker rundocker run [选项] 镜像创建并立即启动新容器。
docker psdocker ps默认查看运行中的容器。
docker ps -adocker ps -a查看运行中和已停止的全部容器。
docker stopdocker stop 容器名或ID请求容器停止。
docker startdocker start 容器名或ID再次启动已停止容器。
docker rmdocker rm 容器名或ID删除已停止容器。
docker logsdocker logs 容器名查看容器标准输出和标准错误日志。
docker logs -fdocker logs -f 容器名持续跟随日志,按 Ctrl + C 退出跟随。
docker execdocker exec -it 容器名 bash在运行中的容器里启动交互命令。

docker exec 只对运行中的容器有效。docker logs 则通常也能查看已停止但尚未删除容器保留的日志。docker rm 通常要求容器已经停止;若明确需要强制删除,docker rm -f 会先终止容器,应先确认名称和数据是否已持久化。


Nginx 练习:走完一次完整生命周期

课件要求在 Docker Hub 搜索 Nginx,然后依次拉取、查看、运行、停止、重启、进入、删除容器。可以按下面顺序练习:

# 1. 拉取并确认本地镜像
docker pull nginx
docker images

# 2. 创建后台容器,演示端口映射
docker run -d --name nginx -p 8080:80 nginx
docker ps

# 3. 停止后重新启动
docker stop nginx
docker start nginx

# 4. 进入运行中的容器
docker exec -it nginx bash

# 5. 退出容器 Shell 后,停止并删除容器
exit
docker stop nginx
docker rm nginx

课件接着要求修改容器内 /usr/share/nginx/html/index.html 并部署静态资源。直接在容器内改文件可以快速观察效果,但容器删掉后改动也会消失。下一篇的数据卷和本地目录挂载,就是为这类配置、静态文件和数据库数据提供可持续的存储边界。


本篇命令清单

# 传统 MySQL 安装回顾
rpm -qa | grep mysql
rpm -qa | grep mariadb
tar -xvf mysql-8.0.30-linux-glibc2.12-x86_64.tar.xz
mv mysql-8.0.30-linux-glibc2.12-x86_64 /usr/local/mysql
source /etc/profile
groupadd mysql
useradd -r -g mysql -s /bin/false mysql
mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
systemctl start mysql

# Docker MySQL
docker run -d --name mysql -p 3307:3306 -e TZ=Asia/Shanghai -e MYSQL_ROOT_PASSWORD=123 mysql:8

# 镜像
docker pull 镜像名:标签
docker push 仓库/镜像名:标签
docker images
docker rmi 镜像名:标签
docker save -o 镜像文件.tar 镜像名:标签
docker load -i 镜像文件.tar

# 容器
docker ps
docker ps -a
docker stop 容器名
docker start 容器名
docker rm 容器名
docker logs -f 容器名
docker exec -it 容器名 bash

Docker 命令的完整参考可查看 Docker CLI 官方文档。下一篇会把“容器运行起来”推进到“数据不会丢、镜像可自定义、服务能按名称通信”。