Docker 常用操作与 MySQL / Redis 容器实战笔记

Docker 常用操作与 MySQL / Redis 容器实战笔记

2026/6/23
Project Learning DockerMySQLRedisFastAPIDocker Compose

Docker 常用操作与 MySQL / Redis 容器实战笔记

适合对象:刚开始学习 Docker、FastAPI、数据库、Redis 的后端初学者。
目标:理解 Docker 的基本概念、常用命令、容器网络、数据卷、MySQL/Redis 容器创建,以及后端项目如何连接数据库和 Redis。


目录

  1. Docker 是什么
  2. 为什么后端开发必须学 Docker
  3. Docker 核心概念
  4. Docker 命令总览
  5. 镜像 image 常用命令
  6. 容器 container 常用命令
  7. 端口映射怎么理解
  8. 环境变量怎么理解
  9. 数据卷 volume 怎么理解
  10. Docker 网络怎么理解
  11. 用 Docker 创建 MySQL 容器
  12. 用 Docker 创建 Redis 容器
  13. FastAPI 如何连接 MySQL 和 Redis
  14. Docker Compose 入门
  15. FastAPI + MySQL + Redis 的 Compose 示例
  16. 常见排错命令
  17. Windows PowerShell 常用操作
  18. 企业项目里怎么使用 Docker
  19. 你必须背熟的命令清单
  20. 参考资料

1. Docker 是什么

Docker 可以理解为:

把一个程序和它运行需要的环境一起打包,然后在任何机器上用同样的方式运行。

比如你写了一个 FastAPI 项目,它可能依赖:

Python 3.11
FastAPI
Uvicorn
SQLAlchemy
MySQL
Redis
系统依赖库
环境变量
启动命令

如果不用 Docker,你在自己电脑上能跑,同学电脑上可能跑不起来,服务器上又要重新装一遍环境。

用了 Docker 后,可以把这些东西打包成镜像,然后用容器运行。


2. 为什么后端开发必须学 Docker

企业项目里 Docker 很常见,因为它解决了几个问题:

1. 环境一致:开发环境、测试环境、生产环境尽量一致
2. 部署方便:一条命令启动服务
3. 服务隔离:MySQL、Redis、后端服务互不污染
4. 方便协作:同事 clone 项目后直接 docker compose up
5. 易于扩展:以后可以迁移到 Kubernetes、云服务器、CI/CD

你以后做 FastAPI 企业项目,大概率会遇到:

FastAPI 容器
PostgreSQL / MySQL 容器
Redis 容器
Elasticsearch 容器
Nginx / Traefik 容器
Celery Worker 容器

3. Docker 核心概念

3.1 镜像 image

镜像是一个“模板”。

例如:

mysql:8.0
redis:7
python:3.11-slim
nginx:alpine

你可以把镜像理解成:

Python 类

3.2 容器 container

容器是镜像运行起来后的实例。

你可以把容器理解成:

Python 对象

关系类似:

class MySQLImage:
    pass

mysql_container = MySQLImage()

Docker 里则是:

docker run mysql:8.0

意思是:

用 mysql:8.0 这个镜像创建并启动一个 MySQL 容器。

3.3 Dockerfile

Dockerfile 是构建镜像的说明书。

例如 FastAPI 项目的 Dockerfile:

FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt

COPY . .

CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

逐行理解:

FROM python:3.11-slim
基于 Python 3.11 的轻量镜像

WORKDIR /app
设置容器里的工作目录

COPY requirements.txt .
把本地 requirements.txt 复制到容器当前目录

RUN pip install ...
构建镜像时安装依赖

COPY . .
把项目代码复制进容器

CMD [...]
容器启动时执行的命令

3.4 Docker Compose

Docker Compose 是用一个 YAML 文件管理多个容器。

比如一个项目需要:

FastAPI
MySQL
Redis

不用 Compose 的话,你要敲很多条 docker run

用了 Compose 之后,只要:

docker compose up -d

它会自动启动所有服务。


3.5 仓库 registry

Docker Hub 是最常见的镜像仓库。

你执行:

docker pull redis:7

Docker 会从 Docker Hub 拉取 Redis 镜像。


4. Docker 命令总览

Docker 命令大致分几类:

docker version        查看版本
docker info           查看 Docker 系统信息

docker images         查看本地镜像
docker pull           拉取镜像
docker rmi            删除镜像

docker ps             查看运行中的容器
docker ps -a          查看所有容器
docker run            创建并启动容器
docker start          启动已存在容器
docker stop           停止容器
docker restart        重启容器
docker rm             删除容器
docker logs           查看容器日志
docker exec           进入容器执行命令
docker inspect        查看容器详细信息

docker network ls     查看网络
docker network create 创建网络
docker network rm     删除网络

docker volume ls      查看数据卷
docker volume create  创建数据卷
docker volume rm      删除数据卷

docker compose up     启动 Compose 项目
docker compose down   停止并删除 Compose 容器
docker compose logs   查看 Compose 日志
docker compose ps     查看 Compose 服务
docker compose exec   进入 Compose 服务容器

5. 镜像 image 常用命令

5.1 查看本地镜像

docker images

或者:

docker image ls

输出类似:

REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
mysql        8.0       xxxxxxxx       2 weeks ago    600MB
redis        7         xxxxxxxx       3 weeks ago    120MB

含义:

REPOSITORY:镜像名
TAG:版本标签
IMAGE ID:镜像唯一 ID
SIZE:镜像大小

5.2 拉取镜像

docker pull mysql:8.0
docker pull redis:7
docker pull python:3.11-slim

不写 tag 时,默认通常是 latest

docker pull redis

等价于:

docker pull redis:latest

企业项目里建议写明确版本,不建议无脑 latest。

推荐:

mysql:8.0
redis:7
python:3.11-slim

5.3 删除镜像

docker rmi redis:7

如果镜像正在被容器使用,需要先删除相关容器。

强制删除:

docker rmi -f redis:7

5.4 查看镜像详细信息

docker inspect redis:7

6. 容器 container 常用命令

6.1 查看正在运行的容器

docker ps

6.2 查看所有容器

docker ps -a

包括已经停止的容器。


6.3 启动容器

docker start 容器名或容器ID

例如:

docker start my-redis

6.4 停止容器

docker stop 容器名或容器ID

例如:

docker stop my-redis

6.5 重启容器

docker restart 容器名或容器ID

6.6 删除容器

删除前先停止:

docker stop my-redis
docker rm my-redis

强制删除:

docker rm -f my-redis

6.7 查看容器日志

docker logs my-redis

实时追踪日志:

docker logs -f my-redis

查看最近 100 行:

docker logs --tail 100 my-redis

6.8 进入容器

进入容器执行 shell:

docker exec -it 容器名 bash

如果容器没有 bash,用 sh:

docker exec -it 容器名 sh

例子:

docker exec -it my-mysql bash
docker exec -it my-redis sh

6.9 在容器中执行一次命令

docker exec my-redis redis-cli ping

返回:

PONG

6.10 查看容器详细信息

docker inspect my-redis

常用来查:

容器 IP
端口映射
挂载卷
环境变量
网络信息
启动命令

7. 端口映射怎么理解

容器内部有自己的端口。

你的电脑也有自己的端口。

如果想让你电脑访问容器里的服务,就需要端口映射。

格式:

-p 宿主机端口:容器端口

例如:

docker run -d --name my-redis -p 6379:6379 redis:7

意思是:

把你电脑的 6379 端口,映射到 Redis 容器内部的 6379 端口。

所以你电脑上可以这样访问 Redis:

redis-cli -h localhost -p 6379 ping

再看 MySQL:

docker run -d --name my-mysql -p 3306:3306 mysql:8.0

意思是:

把你电脑的 3306 端口,映射到 MySQL 容器内部的 3306 端口。

然后本机程序可以连接:

host=localhost
port=3306

容器内部访问和本机访问不一样

这是初学者最容易混的地方。

假设你有两个容器:

fastapi 容器
mysql 容器

FastAPI 容器访问 MySQL 时,不应该写:

localhost

因为在 FastAPI 容器里,localhost 指的是 FastAPI 容器自己,不是 MySQL 容器。

如果两个容器在同一个 Docker 网络里,FastAPI 应该用 MySQL 的容器名或 Compose 服务名:

mysql
db
my-mysql

例如:

mysql+pymysql://root:123456@mysql:3306/app_db

如果是你电脑上的 Python 程序访问 Docker 里的 MySQL,才写:

localhost:3306

记住:

宿主机访问容器:localhost + 映射端口
容器访问容器:服务名/容器名 + 容器内部端口

8. 环境变量怎么理解

环境变量就是运行程序时传进去的配置。

例如创建 MySQL 容器时:

-e MYSQL_ROOT_PASSWORD=123456
-e MYSQL_DATABASE=app_db

意思是:

给 MySQL 容器传入 root 密码
启动时自动创建 app_db 数据库

完整例子:

docker run -d \
  --name my-mysql \
  -e MYSQL_ROOT_PASSWORD=123456 \
  -e MYSQL_DATABASE=app_db \
  -p 3306:3306 \
  mysql:8.0

FastAPI 里也经常用环境变量:

DATABASE_URL=mysql+pymysql://root:123456@mysql:3306/app_db
REDIS_HOST=redis
REDIS_PORT=6379

为什么用环境变量?

因为不同环境配置不同:

本地开发数据库地址
测试环境数据库地址
生产环境数据库地址

不能把密码和服务器地址硬编码到代码里。


9. 数据卷 volume 怎么理解

容器可以删除,但数据库数据不能跟着丢。

如果你直接运行 MySQL:

docker run -d --name my-mysql mysql:8.0

容器删了,里面的数据也可能没了。

所以要用 volume 保存数据。

创建卷:

docker volume create mysql-data

运行 MySQL 时挂载卷:

docker run -d \
  --name my-mysql \
  -e MYSQL_ROOT_PASSWORD=123456 \
  -e MYSQL_DATABASE=app_db \
  -p 3306:3306 \
  -v mysql-data:/var/lib/mysql \
  mysql:8.0

这里:

mysql-data 是 Docker 管理的数据卷
/var/lib/mysql 是 MySQL 容器内部真正存数据的位置

含义:

把容器里的 /var/lib/mysql 存到 Docker volume mysql-data 里。

即使删除容器:

docker rm -f my-mysql

数据卷还在:

docker volume ls

重新用同一个 volume 启动 MySQL,数据还在。


bind mount 和 volume 的区别

volume

-v mysql-data:/var/lib/mysql

Docker 管理数据位置。

适合:

数据库数据
Redis 持久化数据
生产服务数据

bind mount

-v D:/code/myapp:/app

把你电脑上的目录挂到容器里。

适合:

开发时挂载代码
配置文件
日志目录

10. Docker 网络怎么理解

Docker 网络是理解“容器如何连接数据库和 Redis”的关键。

10.1 默认 bridge 网络

Docker 默认有一个 bridge 网络。

你可以查看:

docker network ls

输出类似:

NETWORK ID     NAME      DRIVER
xxxxxx         bridge    bridge
xxxxxx         host      host
xxxxxx         none      null

10.2 自定义网络

推荐创建自己的网络:

docker network create app-net

然后 MySQL、Redis、FastAPI 都加入这个网络:

docker run -d --name mysql --network app-net mysql:8.0
docker run -d --name redis --network app-net redis:7
docker run -d --name backend --network app-net your-fastapi-image

在同一个自定义网络里,容器可以通过容器名互相访问:

backend 访问 mysql:host=mysql,port=3306
backend 访问 redis:host=redis,port=6379

这就是 Docker 容器连接数据库和 Redis 的核心原理。


10.3 为什么容器名可以当域名?

Docker 的自定义 bridge 网络会提供容器名 DNS 解析。

也就是说,在同一个 Docker 网络里:

mysql 这个名字可以解析到 MySQL 容器 IP
redis 这个名字可以解析到 Redis 容器 IP

所以代码里可以写:

REDIS_HOST = "redis"
MYSQL_HOST = "mysql"

而不是写 IP。


10.4 Compose 里的服务名就是网络名

在 Docker Compose 里:

services:
  backend:
    ...
  mysql:
    ...
  redis:
    ...

Compose 会自动创建一个项目网络。

同一个 Compose 项目下,服务之间可以通过服务名访问:

backend 访问 mysql:mysql:3306
backend 访问 redis:redis:6379

这就是为什么企业项目配置里经常看到:

MYSQL_HOST=mysql
REDIS_HOST=redis

11. 用 Docker 创建 MySQL 容器

11.1 最简单启动 MySQL

docker run -d \
  --name my-mysql \
  -e MYSQL_ROOT_PASSWORD=123456 \
  -p 3306:3306 \
  mysql:8.0

解释:

docker run      创建并启动容器
-d              后台运行
--name          容器名
-e              环境变量
-p              端口映射
mysql:8.0       使用 mysql 8.0 镜像

11.2 启动时自动创建数据库

docker run -d \
  --name my-mysql \
  -e MYSQL_ROOT_PASSWORD=123456 \
  -e MYSQL_DATABASE=app_db \
  -p 3306:3306 \
  mysql:8.0

启动后会自动创建:

app_db

11.3 创建普通用户和密码

docker run -d \
  --name my-mysql \
  -e MYSQL_ROOT_PASSWORD=123456 \
  -e MYSQL_DATABASE=app_db \
  -e MYSQL_USER=app_user \
  -e MYSQL_PASSWORD=app_password \
  -p 3306:3306 \
  mysql:8.0

含义:

root 用户密码:123456
创建数据库:app_db
创建普通用户:app_user
普通用户密码:app_password

企业项目里通常不建议业务代码直接用 root 连接数据库,而是使用普通用户。


11.4 带数据卷启动 MySQL

推荐写法:

docker volume create mysql-data
docker run -d \
  --name my-mysql \
  -e MYSQL_ROOT_PASSWORD=123456 \
  -e MYSQL_DATABASE=app_db \
  -e MYSQL_USER=app_user \
  -e MYSQL_PASSWORD=app_password \
  -p 3306:3306 \
  -v mysql-data:/var/lib/mysql \
  mysql:8.0

11.5 测试 MySQL 是否启动成功

查看日志:

docker logs -f my-mysql

进入 MySQL 容器:

docker exec -it my-mysql mysql -uroot -p

输入密码:

123456

查看数据库:

SHOW DATABASES;

切换数据库:

USE app_db;

查看表:

SHOW TABLES;

退出:

exit;

11.6 从宿主机连接 MySQL

如果你电脑安装了 MySQL 客户端:

mysql -h 127.0.0.1 -P 3306 -uroot -p

输入密码:

123456

也可以用 DataGrip、Navicat、DBeaver:

Host: localhost
Port: 3306
User: root
Password: 123456
Database: app_db

11.7 删除 MySQL 容器

docker rm -f my-mysql

注意:如果使用了 volume,数据卷不会自动删除。

删除数据卷:

docker volume rm mysql-data

11.8 MySQL 常见问题

问题 1:端口被占用

报错类似:

Bind for 0.0.0.0:3306 failed: port is already allocated

原因:

你电脑已有 MySQL 占用了 3306
或者另一个容器占用了 3306

解决:

docker ps

找到占用端口的容器并停止:

docker stop 容器名

或者换宿主机端口:

-p 3307:3306

这时宿主机连接:

localhost:3307

容器内其他服务连接仍然是:

mysql:3306

问题 2:删了容器重新建,密码没变

如果你挂载了已有 volume,MySQL 初始化变量只在首次初始化数据目录时生效。

也就是说,第一次创建数据库时用的密码会保存在 volume 里。

你之后换:

MYSQL_ROOT_PASSWORD

不一定会生效。

解决方法:

docker rm -f my-mysql
docker volume rm mysql-data

然后重新创建。


12. 用 Docker 创建 Redis 容器

12.1 最简单启动 Redis

docker run -d \
  --name my-redis \
  -p 6379:6379 \
  redis:7

解释:

--name my-redis       容器名
-p 6379:6379          宿主机 6379 映射到容器 6379
redis:7               使用 Redis 7 镜像

12.2 测试 Redis

方式一:在容器里执行 redis-cli:

docker exec -it my-redis redis-cli

然后:

PING

返回:

PONG

设置 key:

SET name zhangsan

读取 key:

GET name

返回:

"zhangsan"

退出:

exit

方式二:直接执行一次命令:

docker exec my-redis redis-cli ping

返回:

PONG

12.3 带持久化启动 Redis

Redis 默认主要是内存数据库。

如果你想让 Redis 写入数据到磁盘,可以这样:

docker volume create redis-data
docker run -d \
  --name my-redis \
  -p 6379:6379 \
  -v redis-data:/data \
  redis:7 redis-server --appendonly yes

解释:

-v redis-data:/data
把 Redis 数据目录持久化到 Docker volume

redis-server --appendonly yes
开启 AOF 持久化

12.4 设置 Redis 密码

docker run -d \
  --name my-redis \
  -p 6379:6379 \
  redis:7 redis-server --requirepass 123456

连接:

docker exec -it my-redis redis-cli

认证:

AUTH 123456
PING

或者一条命令:

docker exec -it my-redis redis-cli -a 123456 ping

12.5 删除 Redis 容器

docker rm -f my-redis

删除数据卷:

docker volume rm redis-data

13. FastAPI 如何连接 MySQL 和 Redis

这里是你一定要搞懂的重点。


13.1 本地 Python 连接 Docker MySQL

假设 MySQL 容器这样启动:

docker run -d \
  --name my-mysql \
  -e MYSQL_ROOT_PASSWORD=123456 \
  -e MYSQL_DATABASE=app_db \
  -p 3306:3306 \
  mysql:8.0

你的 FastAPI 是在本机直接运行:

uvicorn app.main:app --reload

那么连接地址应该是:

localhost:3306

SQLAlchemy URL:

DATABASE_URL = "mysql+pymysql://root:123456@localhost:3306/app_db"

因为:

FastAPI 在你电脑上
MySQL 在 Docker 容器里
Docker 把容器 3306 映射到了你电脑 localhost:3306

13.2 FastAPI 容器连接 MySQL 容器

如果 FastAPI 也在 Docker 容器里,MySQL 也在 Docker 容器里。

这时不能写:

localhost

错误写法:

DATABASE_URL = "mysql+pymysql://root:123456@localhost:3306/app_db"

为什么?

因为 FastAPI 容器里的 localhost 指 FastAPI 容器自己,不是 MySQL 容器。

正确写法:

DATABASE_URL = "mysql+pymysql://root:123456@mysql:3306/app_db"

其中:

mysql 是 Compose 里的服务名,或者 docker run 时的容器名

13.3 本地 Python 连接 Docker Redis

Redis 容器:

docker run -d --name my-redis -p 6379:6379 redis:7

FastAPI 在本机运行时:

import redis

r = redis.Redis(host="localhost", port=6379, db=0)

print(r.ping())

13.4 FastAPI 容器连接 Redis 容器

如果 FastAPI 也在 Docker 容器里:

import redis

r = redis.Redis(host="redis", port=6379, db=0)

其中:

redis 是 Compose 服务名,或者容器名

13.5 一句话总结连接规则

你的程序在宿主机运行:
    连接 localhost + 映射端口

你的程序在另一个容器运行:
    连接 服务名/容器名 + 容器内部端口

13.6 FastAPI 示例:连接 MySQL

安装依赖:

pip install sqlalchemy pymysql

示例:

from sqlalchemy import create_engine, text

DATABASE_URL = "mysql+pymysql://root:123456@localhost:3306/app_db"

engine = create_engine(DATABASE_URL)

with engine.connect() as conn:
    result = conn.execute(text("SELECT 1"))
    print(result.scalar())

如果在 Docker Compose 里的 backend 容器中运行,则改成:

DATABASE_URL = "mysql+pymysql://root:123456@mysql:3306/app_db"

13.7 FastAPI 示例:连接 Redis

安装依赖:

pip install redis

代码:

from fastapi import FastAPI
import redis

app = FastAPI()

r = redis.Redis(host="localhost", port=6379, db=0, decode_responses=True)

@app.get("/redis/ping")
def redis_ping():
    return {"pong": r.ping()}

@app.post("/cache/{key}")
def set_cache(key: str, value: str):
    r.set(key, value, ex=60)
    return {"message": "ok", "key": key, "value": value}

@app.get("/cache/{key}")
def get_cache(key: str):
    value = r.get(key)
    return {"key": key, "value": value}

如果 FastAPI 在 Compose 容器里:

r = redis.Redis(host="redis", port=6379, db=0, decode_responses=True)

14. Docker Compose 入门

Docker Compose 用 compose.ymldocker-compose.yml 管理多容器项目。

示例:

services:
  backend:
    build: .
    ports:
      - "8000:8000"

  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_DATABASE: app_db
    ports:
      - "3306:3306"

  redis:
    image: redis:7
    ports:
      - "6379:6379"

启动:

docker compose up -d

查看服务:

docker compose ps

查看日志:

docker compose logs -f

停止并删除容器:

docker compose down

停止并删除容器 + 数据卷:

docker compose down -v

14.1 depends_on 是什么

depends_on:
  - mysql
  - redis

表示:

backend 服务启动前,先启动 mysql 和 redis

注意:

depends_on 只能保证启动顺序,不一定保证数据库已经完全 ready。

企业项目里更严谨的做法是加 healthcheck,或者在应用启动时做重试。


14.2 environment 是什么

environment:
  MYSQL_ROOT_PASSWORD: 123456

等价于 docker run 里的:

-e MYSQL_ROOT_PASSWORD=123456

14.3 volumes 是什么

volumes:
  - mysql-data:/var/lib/mysql

表示:

把 MySQL 数据保存到 mysql-data 这个 Docker volume 中。

文件底部还需要声明:

volumes:
  mysql-data:

14.4 ports 是什么

ports:
  - "3306:3306"

格式:

宿主机端口:容器端口

15. FastAPI + MySQL + Redis 的 Compose 示例

项目结构:

my-fastapi-app/
├── app/
│   └── main.py
├── requirements.txt
├── Dockerfile
└── compose.yml

15.1 requirements.txt

fastapi
uvicorn[standard]
sqlalchemy
pymysql
redis

15.2 Dockerfile

FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt

COPY . .

CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

15.3 app/main.py

from fastapi import FastAPI
from sqlalchemy import create_engine, text
import redis
import os

app = FastAPI()

MYSQL_HOST = os.getenv("MYSQL_HOST", "mysql")
MYSQL_PORT = os.getenv("MYSQL_PORT", "3306")
MYSQL_USER = os.getenv("MYSQL_USER", "root")
MYSQL_PASSWORD = os.getenv("MYSQL_PASSWORD", "123456")
MYSQL_DATABASE = os.getenv("MYSQL_DATABASE", "app_db")

DATABASE_URL = (
    f"mysql+pymysql://{MYSQL_USER}:{MYSQL_PASSWORD}"
    f"@{MYSQL_HOST}:{MYSQL_PORT}/{MYSQL_DATABASE}"
)

engine = create_engine(DATABASE_URL, pool_pre_ping=True)

REDIS_HOST = os.getenv("REDIS_HOST", "redis")
REDIS_PORT = int(os.getenv("REDIS_PORT", "6379"))

r = redis.Redis(
    host=REDIS_HOST,
    port=REDIS_PORT,
    db=0,
    decode_responses=True,
)

@app.get("/")
def root():
    return {"message": "FastAPI + MySQL + Redis is running"}

@app.get("/mysql/ping")
def mysql_ping():
    with engine.connect() as conn:
        result = conn.execute(text("SELECT 1"))
        return {"mysql": result.scalar()}

@app.get("/redis/ping")
def redis_ping():
    return {"redis": r.ping()}

@app.post("/cache/{key}")
def set_cache(key: str, value: str):
    r.set(key, value, ex=60)
    return {"message": "cached", "key": key, "value": value}

@app.get("/cache/{key}")
def get_cache(key: str):
    return {"key": key, "value": r.get(key)}

15.4 compose.yml

services:
  backend:
    build: .
    container_name: fastapi-backend
    ports:
      - "8000:8000"
    environment:
      MYSQL_HOST: mysql
      MYSQL_PORT: 3306
      MYSQL_USER: root
      MYSQL_PASSWORD: 123456
      MYSQL_DATABASE: app_db
      REDIS_HOST: redis
      REDIS_PORT: 6379
    depends_on:
      - mysql
      - redis

  mysql:
    image: mysql:8.0
    container_name: fastapi-mysql
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_DATABASE: app_db
    ports:
      - "3306:3306"
    volumes:
      - mysql-data:/var/lib/mysql

  redis:
    image: redis:7
    container_name: fastapi-redis
    ports:
      - "6379:6379"
    volumes:
      - redis-data:/data

volumes:
  mysql-data:
  redis-data:

15.5 启动项目

docker compose up -d --build

查看状态:

docker compose ps

查看日志:

docker compose logs -f backend

访问:

http://localhost:8000/docs

测试:

GET /mysql/ping
GET /redis/ping
POST /cache/name?value=zhangsan
GET /cache/name

16. 常见排错命令

16.1 查看所有容器

docker ps -a

16.2 查看某个容器日志

docker logs 容器名

实时查看:

docker logs -f 容器名

16.3 查看 Compose 日志

docker compose logs -f

只看 backend:

docker compose logs -f backend

只看 MySQL:

docker compose logs -f mysql

只看 Redis:

docker compose logs -f redis

16.4 进入 backend 容器

docker compose exec backend sh

如果有 bash:

docker compose exec backend bash

16.5 进入 MySQL

docker compose exec mysql mysql -uroot -p

输入密码:

123456

16.6 进入 Redis

docker compose exec redis redis-cli

测试:

PING

16.7 查看网络

docker network ls

查看某个网络详情:

docker network inspect 网络名

16.8 查看数据卷

docker volume ls

查看卷详情:

docker volume inspect mysql-data

16.9 清理停止的容器

docker container prune

16.10 清理没用的镜像

docker image prune

清理所有没被使用的资源:

docker system prune

谨慎使用,可能删掉你暂时不用但之后还要用的镜像。


17. Windows PowerShell 常用操作

17.1 查看 Docker 版本

docker --version
docker compose version

17.2 启动 Redis

docker run -d --name my-redis -p 6379:6379 redis:7

测试:

docker exec my-redis redis-cli ping

看到:

PONG

说明成功。


17.3 启动 MySQL

docker run -d `
  --name my-mysql `
  -e MYSQL_ROOT_PASSWORD=123456 `
  -e MYSQL_DATABASE=app_db `
  -p 3306:3306 `
  mysql:8.0

PowerShell 换行符是反引号:

`

不是 Linux/macOS 的反斜杠:

\

如果嫌麻烦,可以写成一行:

docker run -d --name my-mysql -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_DATABASE=app_db -p 3306:3306 mysql:8.0

17.4 查看容器

docker ps
docker ps -a

17.5 停止和删除

docker stop my-redis
docker rm my-redis

强制删除:

docker rm -f my-redis

18. 企业项目里怎么使用 Docker

企业项目里一般不会手动一条条 docker run。

更多是用 Compose 或 Kubernetes。

本地开发常见:

docker compose up -d

项目里常见文件:

Dockerfile
compose.yml
compose.override.yml
.env
.env.example

常见服务:

backend
frontend
mysql / postgres
redis
elasticsearch
nginx
worker
scheduler

企业项目里的后端配置通常来自环境变量:

DATABASE_URL=mysql+pymysql://app_user:app_password@mysql:3306/app_db
REDIS_HOST=redis
REDIS_PORT=6379
SECRET_KEY=xxx
ENVIRONMENT=local

代码读取环境变量:

import os

DATABASE_URL = os.getenv("DATABASE_URL")
REDIS_HOST = os.getenv("REDIS_HOST", "redis")

企业项目中的服务连接原则

后端容器连接数据库:
    使用数据库服务名 + 容器端口

后端容器连接 Redis:
    使用 Redis 服务名 + 容器端口

宿主机浏览器访问后端:
    使用 localhost + ports 映射端口

宿主机数据库客户端访问数据库:
    使用 localhost + ports 映射端口

例如:

services:
  backend:
    environment:
      DATABASE_URL: mysql+pymysql://root:123456@mysql:3306/app_db
      REDIS_HOST: redis

  mysql:
    ports:
      - "3306:3306"

  redis:
    ports:
      - "6379:6379"

19. 你必须背熟的命令清单

基础

docker --version
docker compose version
docker info

镜像

docker images
docker pull redis:7
docker pull mysql:8.0
docker rmi 镜像名

容器

docker ps
docker ps -a
docker run -d --name my-redis -p 6379:6379 redis:7
docker start my-redis
docker stop my-redis
docker restart my-redis
docker rm -f my-redis
docker logs -f my-redis
docker exec -it my-redis redis-cli
docker inspect my-redis

MySQL

docker run -d --name my-mysql -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_DATABASE=app_db -p 3306:3306 mysql:8.0
docker logs -f my-mysql
docker exec -it my-mysql mysql -uroot -p

Redis

docker run -d --name my-redis -p 6379:6379 redis:7
docker exec my-redis redis-cli ping
docker exec -it my-redis redis-cli

网络

docker network ls
docker network create app-net
docker network inspect app-net
docker network rm app-net

数据卷

docker volume ls
docker volume create mysql-data
docker volume inspect mysql-data
docker volume rm mysql-data

Compose

docker compose up -d
docker compose up -d --build
docker compose ps
docker compose logs -f
docker compose logs -f backend
docker compose exec backend sh
docker compose exec mysql mysql -uroot -p
docker compose exec redis redis-cli
docker compose down
docker compose down -v

20. 参考资料

以下是官方资料,建议优先看这些,不要一开始就看杂乱博客。

  1. Docker docker run 官方文档
    https://docs.docker.com/reference/cli/docker/container/run/

  2. Docker bridge network 官方文档
    https://docs.docker.com/engine/network/drivers/bridge/

  3. Docker Compose services 官方文档
    https://docs.docker.com/reference/compose-file/services/

  4. MySQL Official Image
    https://hub.docker.com/_/mysql

  5. Redis Official Image
    https://hub.docker.com/_/redis


最后总结

你现在要形成一个固定心智模型:

镜像 image:
    程序运行模板

容器 container:
    镜像跑起来后的实例

端口映射 ports:
    让宿主机能访问容器服务

环境变量 environment:
    给容器传配置

数据卷 volume:
    保存容器里的重要数据

网络 network:
    让容器之间可以互相访问

Docker Compose:
    一次管理多个容器

连接规则一定要背下来:

宿主机访问容器:
    localhost + 映射端口

容器访问容器:
    服务名/容器名 + 容器内部端口

例如:

本机 FastAPI 访问 Docker MySQL:
    localhost:3306

Docker 里的 FastAPI 访问 Docker 里的 MySQL:
    mysql:3306

本机 FastAPI 访问 Docker Redis:
    localhost:6379

Docker 里的 FastAPI 访问 Docker 里的 Redis:
    redis:6379

这就是 Docker + 数据库 + Redis 连接的核心。