缘博客
发布日期

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.d 与 chkconfig 是课件的 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:latest。latest 只是一个可变标签,不是“永远稳定的最新版本”保证。课程演示和临时试验可以使用它,项目部署应固定明确版本,必要时固定镜像摘要(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 官方文档。下一篇会把“容器运行起来”推进到“数据不会丢、镜像可自定义、服务能按名称通信”。