CentOS Stream 9入门学习教程,从入门到精通,CentOS Stream 9 的 Docker 容器 —— 语法详解与实战案例(16)

CentOS Stream 9 的 Docker 容器 ------ 语法详解与实战案例

系统环境:CentOS Stream 9 x86_64

Docker 版本:26.1(或 Podman 4.9)

目标:掌握容器化部署核心技能


一、云计算与容器概述

云计算:通过网络提供计算资源(CPU、内存、存储、网络)的服务模式。
三种服务模型:

类型 说明 示例
IaaS(基础设施即服务) 提供虚拟机、存储、网络等基础资源 AWS EC2, Azure VM
PaaS(平台即服务) 提供开发运行平台(含中间件、数据库等) Heroku, Google App Engine
SaaS(软件即服务) 直接提供应用程序 Gmail, Office 365

容器技术:轻量级虚拟化,共享宿主机内核,隔离进程、文件系统、网络。
容器 vs 虚拟机:

对比项 容器 虚拟机
启动速度 秒级 分钟级
资源占用 极低 高(需完整 OS)
隔离性 进程级 硬件级
镜像大小 MB 级 GB 级
适用场景 微服务、CI/CD、快速部署 完整系统模拟、强隔离需求

主流容器技术

  • Docker:最流行,生态完善,企业广泛使用
  • Podman:Red Hat 主推,无守护进程,rootless 安全,兼容 Docker CLI
  • Containerd:底层容器运行时,K8s 默认使用

本章重点:Docker + Podman 基础 + Nginx/MySQL 容器化部署


二、Docker 技术详解


2.1 Docker 核心概念

概念 说明
镜像(Image) 只读模板,包含运行环境和应用程序(如 ubuntu:22.04, nginx:latest)
容器(Container) 镜像的运行实例,可启动、停止、删除
仓库(Registry) 存储镜像的地方(Docker Hub, Harbor, 阿里云镜像仓库)
Dockerfile 定义镜像构建步骤的文本文件
docker-compose.yml 定义多容器应用的编排文件

2.2 Docker 安装(CentOS Stream 9)

✅ 安装 Docker Engine:

bash 复制代码
# 卸载旧版本(如有)
sudo dnf remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine

# 安装依赖
sudo dnf install -y dnf-plugins-core
sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# 安装 Docker Engine、CLI、Containerd
sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# 启动并设置开机自启
sudo systemctl start docker
sudo systemctl enable docker

# 验证安装
sudo docker run hello-world

✅ 将当前用户加入 docker 组(免 sudo):

bash 复制代码
sudo usermod -aG docker $USER
newgrp docker  # 立即生效组权限(或重新登录)

# 验证无需 sudo
docker run hello-world

✅ 查看版本:

bash 复制代码
docker --version
docker info

2.3 Docker 常用命令语法详解

① 镜像管理
bash 复制代码
# 拉取镜像
docker pull nginx:latest

# 查看本地镜像
docker images

# 删除镜像(需无容器使用)
docker rmi nginx:latest

# 构建镜像(从 Dockerfile)
docker build -t myapp:1.0 .

# 打标签
docker tag myapp:1.0 myregistry.com/myapp:1.0

# 推送镜像
docker push myregistry.com/myapp:1.0
② 容器管理
bash 复制代码
# 运行容器(前台)
docker run -it ubuntu:22.04 /bin/bash

# 后台运行 + 端口映射 + 自动重启 + 命名
docker run -d \
  --name mynginx \
  -p 8080:80 \
  --restart unless-stopped \
  nginx:latest

# 查看运行中容器
docker ps

# 查看所有容器(含停止的)
docker ps -a

# 查看容器日志
docker logs mynginx

# 进入运行中的容器
docker exec -it mynginx /bin/bash

# 停止容器
docker stop mynginx

# 启动已停止容器
docker start mynginx

# 删除容器(必须先停止)
docker rm mynginx

# 强制删除运行中容器
docker rm -f mynginx

# 查看容器资源使用
docker stats mynginx
③ 数据卷与挂载
bash 复制代码
# 挂载主机目录到容器
docker run -d \
  --name mynginx \
  -v /home/user/html:/usr/share/nginx/html \
  -p 8080:80 \
  nginx:latest

# 创建命名数据卷
docker volume create myvol

# 使用数据卷
docker run -d \
  --name mynginx \
  -v myvol:/usr/share/nginx/html \
  nginx:latest

# 查看数据卷
docker volume ls
docker volume inspect myvol
④ 网络管理
bash 复制代码
# 查看网络
docker network ls

# 创建自定义网络
docker network create mynet

# 容器加入自定义网络
docker run -d \
  --name mynginx \
  --network mynet \
  nginx:latest

# 容器间通过容器名通信(需在同一网络)
docker run -it --network mynet alpine ping mynginx

2.4 Dockerfile 语法详解(带注释)

✅ 示例:构建自定义 Nginx 镜像,包含自定义首页

dockerfile 复制代码
# Dockerfile

# 基础镜像
FROM nginx:latest

# 维护者信息(可选)
LABEL maintainer="admin@example.com"

# 将本地文件复制到镜像中(相对 Dockerfile 路径)
COPY index.html /usr/share/nginx/html/

# 暴露端口(文档说明,实际需 -p 映射)
EXPOSE 80

# 启动命令(Nginx 默认已设置,可省略)
# CMD ["nginx", "-g", "daemon off;"]

✅ 准备 index.html:

html 复制代码
<!-- index.html -->
<!DOCTYPE html>
<html>
<head><title>My Custom Nginx</title></head>
<body>
    <h1>Hello from Custom Docker Nginx!</h1>
    <p>Deployed on: <%= new Date() %></p>
</body>
</html>

✅ 构建并运行:

bash 复制代码
# 构建镜像(末尾 . 表示当前目录为构建上下文)
docker build -t my-nginx:1.0 .

# 运行容器
docker run -d --name myweb -p 8080:80 my-nginx:1.0

# 访问 http://localhost:8080 查看效果

✅ Dockerfile 指令速查:

指令 作用 示例
FROM 指定基础镜像 FROM ubuntu:22.04
LABEL 添加元数据 LABEL version="1.0"
COPY 复制文件到镜像 COPY app.py /app/
ADD 复制+自动解压 ADD app.tar.gz /app/
RUN 执行命令(构建时) RUN apt update && apt install -y curl
CMD 容器启动默认命令 CMD ["python", "app.py"]
ENTRYPOINT 入口点(不可被覆盖) ENTRYPOINT ["./start.sh"]
EXPOSE 声明端口 EXPOSE 80
ENV 设置环境变量 ENV DEBUG=true
WORKDIR 设置工作目录 WORKDIR /app
VOLUME 声明数据卷 VOLUME ["/data"]

2.5 docker-compose.yml 语法详解

用于定义和运行多容器应用。
✅ 示例:同时部署 Nginx + MySQL

yaml 复制代码
# docker-compose.yml

version: '3.8'  # Compose 文件版本

services:
  # 定义第一个服务:Web 服务器
  web:
    image: nginx:latest
    container_name: my_nginx
    ports:
      - "8080:80"        # 主机端口:容器端口
    volumes:
      - ./html:/usr/share/nginx/html  # 挂载自定义页面
    depends_on:
      - db               # 依赖 db 服务(启动顺序)
    restart: unless-stopped

  # 定义第二个服务:数据库
  db:
    image: mysql:8.0
    container_name: my_mysql
    environment:
      MYSQL_ROOT_PASSWORD: my-secret-pw
      MYSQL_DATABASE: myapp
      MYSQL_USER: appuser
      MYSQL_PASSWORD: app-pass
    ports:
      - "3306:3306"
    volumes:
      - mysql_data:/var/lib/mysql   # 使用命名卷
    restart: unless-stopped

# 定义命名卷(全局)
volumes:
  mysql_data:

✅ 准备自定义页面:

bash 复制代码
mkdir html
echo "<h1>Welcome to My Docker Site!</h1>" > html/index.html

✅ 启动服务:

bash 复制代码
# 启动所有服务(后台)
docker-compose up -d

# 查看服务状态
docker-compose ps

# 查看日志
docker-compose logs web
docker-compose logs db

# 停止服务
docker-compose down

# 重建镜像并启动
docker-compose up -d --build

✅ docker-compose.yml 关键语法:

字段 说明
version Compose 文件格式版本
services 定义多个容器服务
image 使用的镜像
build 指定 Dockerfile 路径(替代 image)
ports 端口映射 "主机:容器"
volumes 数据卷挂载 "主机路径:容器路径""命名卷:容器路径"
environment 设置环境变量
depends_on 启动依赖顺序
restart 重启策略(no, always, unless-stopped)
volumes(根) 定义命名卷

三、Podman 技术详解

Podman:Red Hat 开发,Docker CLI 兼容,无守护进程,支持 rootless,更安全。
✅ 安装 Podman(CentOS Stream 9 默认已安装):

bash 复制代码
# 查看是否已安装
podman --version

# 若未安装:
sudo dnf install -y podman

# 验证
podman run hello-world

✅ Podman 与 Docker 命令对比:

Docker Podman 说明
docker run podman run 完全兼容
docker ps podman ps
docker build podman build
docker-compose podman-compose 需单独安装

✅ 安装 podman-compose:

bash 复制代码
sudo dnf install -y python3-pip
pip3 install podman-compose

✅ 使用示例(与 Docker 几乎一致):

bash 复制代码
# 拉取镜像
podman pull nginx:latest

# 运行容器
podman run -d --name mypodnginx -p 8081:80 nginx:latest

# 查看容器
podman ps

# 查看镜像
podman images

# 无守护进程:直接管理容器进程,更轻量安全

✅ Rootless 模式(推荐):

bash 复制代码
# 普通用户直接运行(无需 sudo)
podman run -d --name rootless-nginx -p 8082:80 nginx:latest

# 查看用户级容器
podman ps -a

# 用户级镜像存储在 ~/.local/share/containers/

✅ 与 Docker 互操作:

bash 复制代码
# 导出 Docker 镜像为 tar
docker save nginx:latest > nginx.tar

# Podman 加载
podman load -i nginx.tar

# 导出 Podman 镜像
podman save nginx:latest -o nginx-podman.tar

✅ Podman 优势:

  • 无 daemon,更安全,资源占用少
  • 支持 rootless,普通用户可运行容器
  • 与 systemd 集成好(podman generate systemd
  • 兼容 Docker CLI 和镜像格式

四、综合案例1:Nginx 容器部署


4.1 案例概述

使用 Docker 部署 Nginx Web 服务器,支持自定义页面、端口映射、数据卷挂载、自动重启。
适用场景:快速搭建静态网站、反向代理、负载均衡测试环境。


4.2 案例详解

✅ 方法一:直接运行官方镜像(快速测试)

bash 复制代码
# 后台运行,映射端口,设置重启策略
docker run -d \
  --name webserver \
  -p 8080:80 \
  --restart unless-stopped \
  nginx:latest

# 验证访问
curl http://localhost:8080
# 应返回默认 Nginx 欢迎页

✅ 方法二:自定义页面 + 数据卷挂载(生产推荐)

bash 复制代码
# 创建本地目录存放自定义页面
mkdir -p ~/myweb/html
echo "<h1>My Docker Nginx Site</h1>" > ~/myweb/html/index.html

# 运行容器并挂载目录
docker run -d \
  --name myweb \
  -p 8080:80 \
  -v ~/myweb/html:/usr/share/nginx/html:ro \  # ro=只读,安全
  --restart unless-stopped \
  nginx:latest

# 验证自定义页面
curl http://localhost:8080
# 输出:My Docker Nginx Site

✅ 方法三:使用 Dockerfile 构建自定义镜像

dockerfile 复制代码
# Dockerfile.custom
FROM nginx:alpine  # 更小体积

# 删除默认欢迎页
RUN rm -f /usr/share/nginx/html/*

# 复制自定义页面
COPY ./html/ /usr/share/nginx/html/

# 暴露端口
EXPOSE 80

# 使用默认启动命令

✅ 构建并运行:

bash 复制代码
# 目录结构:
# .
# ├── Dockerfile.custom
# └── html/
#     └── index.html

docker build -t my-nginx-custom:1.0 -f Dockerfile.custom .

docker run -d --name custom-web -p 8080:80 my-nginx-custom:1.0

✅ 方法四:使用 docker-compose 编排(推荐用于多服务)

yaml 复制代码
# docker-compose-nginx.yml
version: '3.8'

services:
  nginx:
    image: nginx:latest
    container_name: prod_nginx
    ports:
      - "80:80"
    volumes:
      - ./html:/usr/share/nginx/html:ro
      - ./nginx.conf:/etc/nginx/nginx.conf:ro  # 可选:自定义配置
    restart: always
    networks:
      - webnet

networks:
  webnet:
    driver: bridge

✅ 启动:

bash 复制代码
docker-compose -f docker-compose-nginx.yml up -d

五、综合案例2:MySQL 容器部署


5.1 案例概述

使用 Docker 部署 MySQL 8.0 数据库,设置 root 密码、创建数据库和用户,持久化数据卷,支持远程连接。
适用场景:开发测试数据库、微服务后端存储。


5.2 案例详解

✅ 基础运行(不推荐生产)

bash 复制代码
docker run -d \
  --name mysql_db \
  -p 3306:3306 \
  -e MYSQL_ROOT_PASSWORD=secret123 \
  mysql:8.0

# 进入容器测试
docker exec -it mysql_db mysql -uroot -p
# 输入密码 secret123

✅ 生产级部署(推荐):

bash 复制代码
# 创建数据卷(持久化)
docker volume create mysql_data

# 创建配置目录
mkdir -p ~/mysql/conf
mkdir -p ~/mysql/init

# 创建初始化 SQL 脚本(可选)
cat > ~/mysql/init/init.sql <<EOF
CREATE DATABASE IF NOT EXISTS myapp;
CREATE USER 'appuser'@'%' IDENTIFIED BY 'AppPass123!';
GRANT ALL PRIVILEGES ON myapp.* TO 'appuser'@'%';
FLUSH PRIVILEGES;
EOF

# 运行 MySQL 容器
docker run -d \
  --name mysql_prod \
  -p 3306:3306 \
  -e MYSQL_ROOT_PASSWORD=RootPass456! \
  -e MYSQL_DATABASE=myapp \
  -e MYSQL_USER=appuser \
  -e MYSQL_PASSWORD=AppPass123! \
  -v mysql_data:/var/lib/mysql \
  -v ~/mysql/conf:/etc/mysql/conf.d \
  -v ~/mysql/init:/docker-entrypoint-initdb.d \
  --restart unless-stopped \
  mysql:8.0 \
  --character-set-server=utf8mb4 \
  --collation-server=utf8mb4_unicode_ci

# 验证数据库
docker exec -it mysql_prod mysql -uappuser -pAppPass123! -e "SHOW DATABASES;"

✅ 关键参数说明:

  • -e MYSQL_ROOT_PASSWORD:设置 root 密码(必需)
  • -e MYSQL_DATABASE:自动创建数据库
  • -e MYSQL_USER / MYSQL_PASSWORD:创建用户并授权
  • -v ~/mysql/init:/docker-entrypoint-initdb.d:容器首次启动时执行 SQL 脚本
  • --character-set-server=utf8mb4:设置默认字符集

✅ 自定义 MySQL 配置(my.cnf)

ini 复制代码
# ~/mysql/conf/custom.cnf
[mysqld]
max_connections=200
innodb_buffer_pool_size=256M
log-error=/var/log/mysql/error.log
slow_query_log=1
slow_query_log_file=/var/log/mysql/slow.log
long_query_time=2

✅ 使用 docker-compose 部署 MySQL(推荐)

yaml 复制代码
# docker-compose-mysql.yml
version: '3.8'

services:
  mysql:
    image: mysql:8.0
    container_name: mysql_server
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: RootPass456!
      MYSQL_DATABASE: myapp
      MYSQL_USER: appuser
      MYSQL_PASSWORD: AppPass123!
    volumes:
      - mysql_data:/var/lib/mysql
      - ./mysql/conf:/etc/mysql/conf.d
      - ./mysql/init:/docker-entrypoint-initdb.d
    command:
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_unicode_ci
    restart: unless-stopped

volumes:
  mysql_data:

✅ 启动:

bash 复制代码
mkdir -p mysql/conf mysql/init
# 放入 custom.cnf 和 init.sql
docker-compose -f docker-compose-mysql.yml up -d

六、综合性案例:LNMP 环境一键部署

L inux + N ginx + M ySQL + PHP 容器化一键部署
✅ 目录结构:

复制代码
lnmp-project/
├── docker-compose.yml
├── nginx/
│   ├── Dockerfile
│   └── default.conf
├── php/
│   └── Dockerfile
└── html/
    └── index.php

6.1 编写 Dockerfile

nginx/Dockerfile

dockerfile 复制代码
FROM nginx:alpine
COPY default.conf /etc/nginx/conf.d/default.conf
EXPOSE 80

nginx/default.conf

nginx 复制代码
server {
    listen 80;
    server_name localhost;
    root /var/www/html;
    index index.php index.html;

    location ~ \.php$ {
        fastcgi_pass php:9000;  # 转发到 php 服务
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

php/Dockerfile

dockerfile 复制代码
FROM php:8.2-fpm-alpine
RUN docker-php-ext-install mysqli pdo pdo_mysql
WORKDIR /var/www/html

html/index.php

php 复制代码
<?php
echo "<h1>Welcome to LNMP Docker!</h1>";
phpinfo();
?>

6.2 编写 docker-compose.yml

yaml 复制代码
# docker-compose.yml
version: '3.8'

services:
  nginx:
    build: ./nginx
    ports:
      - "80:80"
    volumes:
      - ./html:/var/www/html:ro
    depends_on:
      - php
    restart: unless-stopped

  php:
    build: ./php
    volumes:
      - ./html:/var/www/html
    restart: unless-stopped

  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: testdb
    volumes:
      - mysql_data:/var/lib/mysql
    restart: unless-stopped

volumes:
  mysql_data:

6.3 一键部署

bash 复制代码
cd lnmp-project
docker-compose up -d --build

# 访问 http://localhost
# 应显示 PHP 信息页面

✅ 验证 PHP 连接 MySQL(修改 index.php):

php 复制代码
<?php
$host = 'mysql';
$db   = 'testdb';
$user = 'root';
$pass = 'secret';
$charset = 'utf8mb4';

$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false,
];

try {
    $pdo = new PDO($dsn, $user, $pass, $options);
    echo "<h1>🎉 LNMP 部署成功!</h1>";
    echo "<p>✅ 数据库连接成功!</p>";
} catch (\PDOException $e) {
    throw new \PDOException($e->getMessage(), (int)$e->getCode());
}
?>

✅ Docker/Podman 最佳实践

  1. 使用 .dockerignore:避免上传无用文件,加速构建
  2. 多阶段构建:减小镜像体积
  3. 非 root 用户运行:提升安全性
  4. 健康检查HEALTHCHECK 指令
  5. 资源限制--memory, --cpus
  6. 日志驱动--log-driver=json-file --log-opt max-size=10m
  7. 定期清理docker system prune -a
  8. 使用 Podman:生产环境推荐,更安全轻量

📚 附录:常用命令速查表

功能 Docker 命令 Podman 命令
拉取镜像 docker pull nginx podman pull nginx
列出镜像 docker images podman images
运行容器 docker run -d --name web -p 80:80 nginx podman run -d --name web -p 80:80 nginx
列出容器 docker ps podman ps
查看日志 docker logs web podman logs web
进入容器 docker exec -it web /bin/bash podman exec -it web /bin/bash
构建镜像 docker build -t myapp . podman build -t myapp .
启动编排 docker-compose up -d podman-compose up -d
清理系统 docker system prune -a podman system prune -a

🧩 综合项目扩展建议

  1. 部署 WordPress:Nginx + PHP + MySQL + phpMyAdmin
  2. 搭建私有镜像仓库registry:2 + Nginx HTTPS 代理
  3. CI/CD 集成:Jenkins + Docker 自动构建部署
  4. 监控容器:cAdvisor + Prometheus + Grafana
  5. 容器安全扫描:Trivy / Clair 扫描镜像漏洞
  6. 迁移到 Podman:将现有 Docker 项目无缝迁移至 Podman

这份文档覆盖了 CentOS Stream 9 上 容器技术的全部核心知识点 + 语法细节 + 配置说明 + 实用案例 + 综合项目,所有命令和代码均含详细注释,可直接用于教学、自学或生产环境参考。

相关推荐
非凡ghost7 小时前
FlexiPDF(专业PDF编辑软件)
windows·学习·pdf·软件需求
d111111111d7 小时前
嵌入式面试问题:STM32中指针和数组的本质区别是什么,常用数组存储什么数据?
java·笔记·stm32·单片机·嵌入式硬件·学习
kevin_水滴石穿7 小时前
Docker 健康检查(Healthcheck)
运维·docker·容器
羑悻的小杀马特7 小时前
Docker高阶实战:从镜像构建优化策略实践到MySQL主从集群详解+一主二从容器化实现,一文打通生产级部署!
mysql·docker·容器·镜像实战
Nan_Shu_6147 小时前
学习:Pinia(1)
javascript·vue.js·学习
Century_Dragon7 小时前
MR实训探秘新能源动力系统——虚实融合助力职校拆装检测教学
学习
Darkershadow7 小时前
Python学习之使用笔记本摄像头截屏
python·opencv·学习
深蓝海拓9 小时前
PySide6从0开始学习的笔记(四)QMainWindow
笔记·python·学习·pyqt
深蓝海拓9 小时前
PySide6 的 QSettings简单应用学习笔记
python·学习·pyqt